Bash

在 ksh 和 bash 之間使用 Heredoc 和引用 shell PID 的命令替換不同

  • August 20, 2021

科恩腳本:

#!/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

引用自:https://unix.stackexchange.com/questions/665431