Как сделать приоритетным задание в сценарии?

Why does the script need to redirect, to a file descriptor inherited by the subshell, a copy of its own contents rather than, say, the contents of some other file?

Вы можете использовать любой файл, если все копии скрипта используют один и тот же файл. Использование $0просто привязывает блокировку к самому скрипту :Если вы скопируете скрипт и измените его для какого-либо другого использования, вам не нужно придумывать новое имя для файла блокировки. Это удобно.

Если скрипт вызывается через символическую ссылку, блокируется фактический файл, а не ссылка.

(Конечно, если какой-то процесс запускает сценарий и дает ему выдуманное значение в качестве нулевого аргумента вместо фактического пути, то это ломается. Но это редко делается.)

(I tried using a different file and re-running as above, and the execution order changed)

Вы уверены, что это произошло из-за используемого файла, а не из-за случайного изменения? Как и в случае с конвейером, нет никакого способа быть уверенным в том, в каком порядке команды будут выполняться в cmd1 & cmd. В основном это зависит от планировщика ОС. Я получаю случайные изменения в моей системе.

Why does the script need to redirect, to a file descriptor inherited by the subshell, a copy of a file's contents, anyway?

Похоже, это так, что сама оболочка хранит копию описания файла, удерживающего блокировку, а не только утилита flock. Блокировка, сделанная с помощью flock(2), снимается, когда дескрипторы файлов, имеющие ее, закрываются.

flockимеет два режима: либо взять блокировку на основе имени файла, либо запустить внешнюю команду (, и в этом случае flockсодержит требуемый дескриптор открытого файла ), либо взять дескриптор файла из снаружи, поэтому за его удержание отвечает внешний процесс.

Обратите внимание, что содержимое файла здесь не имеет значения, и копии не делаются. Перенаправление на подоболочку не копирует никаких данных само по себе, оно просто открывает дескриптор файла.

Why does holding an exclusive lock on file descriptor 0 in one shell prevent a copy of the same script, running in a different shell, from getting an exclusive lock on file descriptor 0? Don't shells have their own, separate copies of the standard file descriptors (0, 1, and 2, i.e. STDIN, STDOUT, and STDERR)?

Да, но блокируется файл , а не дескриптор файла. Только один открытый экземпляр файла может одновременно удерживать блокировку.


Я думаю, вы сможете сделать то же самое без подоболочки, используя execдля открытия дескриптора файла блокировки:

$ cat lock.sh
#!/bin/sh

exec 9< "$0"

if ! flock -n -x 9; then
    echo "$$/$1 cannot get flock" 
    exit 0
fi

echo "$$/$1 got the lock"
sleep 2
echo "$$/$1 exit"

$./lock.sh bg &./lock.sh fg ; wait; echo
[1] 11362
11363/fg got the lock
11362/bg cannot get flock
11363/fg exit
[1]+  Done                   ./lock.sh bg
12
01.03.2021, 17:04
2 ответа

Вам нужно просто включить управление заданиями в оболочке с помощьюset -m

#!/bin/bash
set -m
sleep 3 &  # test
sleep 1    # wait some
sleep 4 &  # run program under test
jobs
fg %1

цитата из руководства bash:

-m

Monitor mode. Job control is enabled. This option is on by default for interactive shells on systems that support it (see JOB CONTROL above). Background processes run in a separate process group and a line containing their exit status is printed upon their completion.

22
18.03.2021, 22:28
#!/bin/bash

sleep 3 & sleep_pid=$!
sleep 1
sleep 4 &
wait "$sleep_pid"

Помещение этого sleep 3на передний план было бы эквивалентно ожиданию его завершения. Я предполагаю, что это то, что вы хотите сделать (или, по крайней мере, это эффект , который вы ищете ), и это то, что делает приведенный выше сценарий. Он делает это, сохраняя PID задания в переменной sleep_pid, а затем используя это значение при вызове wait.

Вы также можете использовать идентификатор задания:

#!/bin/bash

sleep 3 &
sleep 1
sleep 4 &
wait %1
22
18.03.2021, 22:28

Теги

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