コーエンスクリプト:
#!/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
bash
976354(の子プロセス)では、子$$
プロセスはコマンド置換を実行してps
から実行を続行するようにフォークされますが、ps
kshではコマンドオーバーライドを実行するプロセスがデフォルトのps
kshフォーク($$
)によって処理されます。
pgrep -P "$$"
スクリプトを解釈するためにシェルを実行するプロセスの子孫をリストします(それ自体ではありません)。 Bashでは、これには最終的にあなたを実行するプロセスが含まれます。これはまさにそれだからですsqlplus
。bash
これにより、コマンド置換プロセスをフォアグラウンドプロセスグループに配置できるため、対話型シェルでの操作の制御が容易になり、Ctrl + Cを押すと中断され、対話的にksh93を見つけることができます。リダイレクトされたコマンドが外部コマンドの場合は実行時。
ただし、kshに関する限り、実行時には実行中のプロセス以外のpgrep -P
子プロセスはありません。実行されるジョブは後で開始されるため、出力は空であり、それについて文句を言います。$$
pgrep
sqlplus
pgrep
sqlplus
define=
実行するプロセスのpidをdefine=<pid>
提供することが重要な場合、より信頼性の高いアプローチは次のとおりです。sqlplus
<pid>
sqlplus
sh -c 'exec sqlplus -s / << EOF
define a=$$
define a
!ptree &a
EOF'
ここでは、を使用しているため、この新しいインスタンスで実行するプロセスがあることexec
がわかります。$$
sh
sqlplus