Так и должно быть:
<my_cmd> 2>file3 | tee file1 file2 > /dev/null
Сначала выполняется перенаправление stderr, а затем tee
получает только stdout.
Вероятно, проблема заключается в том, что процесс, разветвленный screenshot-menu.bash
для выполнения nohup./screenshot.bash -$key
в фоновом режиме, получает SIGHUP
и завершается до того, как nohup
сможет запуститься.
Простой эксперимент, кажется, подтверждает это:
$ alacritty -e sh -c 'nohup sleep 1000 &'
$ pgrep -a sleep
$
strace
выполнение всей команды показывает, что sh
разветвляется, но execve
не выполняется nohup
до того, как разветвленный процесс получит SIGHUP
— когда alacritty
завершается и созданный им псевдотерминал -исчезает — и уходит.
Не ища альтернативных подходов (, которые, вероятно, существуют, когда дело доходит до смешивания терминальных и графических приложений ),Логичное решение состоит в том, чтобы не применять nohup
к команде, которая переходит в фоновый режим, и вместо этого использовать ее в родительском процессе. Например:
$ alacritty -e sh -c 'nohup sh -c "sleep 1000 &"'
$ pgrep -a sleep
625910 sleep 1000
В screenshot-menu.bash
вы можете таким образом изменить эту строку
s|w|r) nohup./screenshot.bash -$key & ;;
в
s|w|r) nohup sh -c "./screenshot.bash \"-$key\" &" ;;
Кроме того, вы можете включить управление заданиями в screenshot-menu.bash
с помощью set -m
и избавиться отnohup
(оболочка запустит фоновые конвейеры (простая команда — это тоже конвейер )в своем собственном процессе групп, и только группа процессов переднего плана доставляется SIGHUP
, когда ее управляющий терминал исчезает ), при условии, что вы можете убедиться, что ничто в screenshot.bash
не пытается читать или записывать на терминал (, т.е. вам нужно явные перенаправления, эквивалентные выполненнымnohup
).
Например, screenshot-menu.bash
может стать:
#!/usr/bin/env bash
set -m
echo 'Select an option:
...
'
case $key in
s|w|r) </dev/null >>./log.txt 2>&1./screenshot.bash "-$key" & ;;
*) echo Canceled. >>./log.txt ;;
esac
См. также:
nohup
.