Bash
在 ksh 和 bash 之間使用 Heredoc 和引用 shell PID 的命令替換不同
科恩腳本:
#!/bin/ksh sqlplus -s / << EOF define a=$(pgrep -P $$) define a !ptree &a EOF
VS
bash 腳本:
#!/bin/bash sqlplus -s / << EOF define a=$(pgrep -P $$) define a !ptree &a EOF
Korn shell 輸出(不按預期工作):
$ /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 shell 輸出(按預期工作):
$ /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 腳本中進行這項工作?
將其更改為:
(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 "$$"
列出執行 shell 以解釋您的腳本的程序的子程序(但從不列出自身)。在 bash 中,這恰好包括最終將執行您的程序,sqlplus
因為bash
碰巧就是這樣做的。這樣做可以使互動式 shell 中的作業控制更容易,因為您可以將命令替換的程序放在前台程序組中,因此當您按 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
。