Использование Heredoc с подстановкой команд, относящейся к PID оболочки, различается между ksh и bash

При использовании API версии 5.0 попробуйте этот патч:

https://gist.githubusercontent.com/rkitover/5c747964cafcebf7222d543e8270fa9a/raw/46308574053fe57bdcbbf1ed2dc61d8e47e3b50f/rtl8821ce_4_19.patch

0
20.08.2021, 08:49
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, и вы обнаружите, что кш93,при интерактивном запуске это также происходит, когда перенаправленная команда является внешней командой.

Но в случае ksh во время работы pgrep -Pнет другого потомка $$, кроме того, который работает pgrep. Тот, который будет запускать sqlplus, будет запущен позже, поэтому вывод pgrepбудет пустым, и ваш sqlplusжалуется на это define=.

Если точка должна передать define=<pid>в sqlplus, где <pid>— pid процесса, который будет выполнять sqlplus, более надежным способом будет:

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

Где, поскольку мы используем exec, мы знаем, что $$в этом новом экземпляре sh— это процесс, который будет выполнять sqlplus.

1
20.08.2021, 10:25

Теги

Похожие вопросы