Heredocを使用してシェルPIDを引用するコマンドの置き換えは、kshとbashの間で異なります。

Heredocを使用してシェルPIDを引用するコマンドの置き換えは、kshとbashの間で異なります。

コーエンスクリプト:

#!/bin/ksh
sqlplus -s / << EOF
define a=$(pgrep -P $$)
define a
!ptree &a
EOF

VS

クンクンスクリプト:

#!/bin/bash
sqlplus -s / << EOF
define a=$(pgrep -P $$)
define a
!ptree &a
EOF

Kornシェル出力(予想どおりに機能しません):

$ /tmp/testsql.ksh
SP2-0137: DEFINE requires a value following equal sign
SP2-0135: symbol a is UNDEFINED
Enter value for a:
SP2-0546: User requested Interrupt or EOF detected.

Bash シェル出力(予想通り動作):

$ /tmp/testsql.bash
DEFINE A               = "2713" (CHAR)
  710 /usr/lib/ssh/sshd
   9574 /usr/lib/ssh/sshd -R
     9578 /usr/lib/ssh/sshd -R
.
.
.
                     2712 /bin/bash /tmp/testsql.sh
                       2713 sqlplus -s /
                         2717 ptree 2713

kshスクリプトでこれを行う方法についてのアイデアはありますか?

答え1

次に変更してください。

(cat; exec ps -o pid,args) << EOF
$(ps -o pid,ppid,args -H)
EOF

何が起こったのか見てください。

を使用すると、bash以下が表示されます。

$ bash ./script
    PID    PPID COMMAND
 428458  428451 /bin/zsh
 976353  428458   bash ./script
 976354  976353     bash ./script
 976355  976354       ps -o pid,ppid,args -H
    PID COMMAND
 428458 /bin/zsh
 976353 bash ./script
 976354 ps -o pid,args
$ ksh93u+m ./script
    PID    PPID COMMAND
 428458  428451 /bin/zsh
 976559  428458   ksh93u+m ./script
 976560  976559     ps -o pid,ppid,args -H
    PID COMMAND
 428458 /bin/zsh
 976559 ksh93u+m ./script
 976562 ps -o pid,args

bash976354(の子プロセス)では、子$$プロセスはコマンド置換を実行してpsから実行を続行するようにフォークされますが、pskshではコマンドオーバーライドを実行するプロセスがデフォルトのpskshフォーク($$)によって処理されます。

pgrep -P "$$"スクリプトを解釈するためにシェルを実行するプロセスの子孫をリストします(それ自体ではありません)。 Bashでは、これには最終的にあなたを実行するプロセスが含まれます。これはまさにそれだからですsqlplusbash

これにより、コマンド置換プロセスをフォアグラウンドプロセスグループに配置できるため、対話型シェルでの操作の制御が容易になり、Ctrl + Cを押すと中断され、対話的にksh93を見つけることができます。リダイレクトされたコマンドが外部コマンドの場合は実行時。

ただし、kshに関する限り、実行時には実行中のプロセス以外のpgrep -P子プロセスはありません。実行されるジョブは後で開始されるため、出力は空であり、それについて文句を言います。$$pgrepsqlpluspgrepsqlplusdefine=

実行するプロセスのpidをdefine=<pid>提供することが重要な場合、より信頼性の高いアプローチは次のとおりです。sqlplus<pid>sqlplus

sh -c 'exec sqlplus -s / << EOF
define a=$$
define a
!ptree &a
EOF'

ここでは、を使用しているため、この新しいインスタンスで実行するプロセスがあることexecがわかります。$$shsqlplus

関連情報