Как периодически проверять, открыт ли STDIN?

Определение количества ссылок с использованием имени

Вы можете использовать команду stat , чтобы получить количество ссылок на данный файл / каталог:

$ stat lib/
  File: ‘lib/’
  Size: 4096        Blocks: 8          IO Block: 4096   directory
Device: fd02h/64770d    Inode: 11666186    Links: 3
Access: (0755/drwxr-xr-x)  Uid: ( 1000/    saml)   Gid: ( 1000/    saml)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2014-03-21 18:16:10.521963381 -0400
Modify: 2014-01-13 17:16:49.438408973 -0500
Change: 2014-01-14 17:57:46.636255446 -0500
 Birth: -

Взглянув на страницу руководства для ] stat :

%h     number of hard links
%i     inode number

Таким образом, вы можете получить только это значение напрямую, используя возможности вывода stat - printf или - format :

$ stat --printf="%h\n" lib/
3

$ stat --format="%h" lib/
3

$ stat -c "%h" lib/
3

Определение количества ссылок с помощью индексного дескриптора

Если, с другой стороны, вы знаете только номер индексного дескриптора, вы можете работать в обратном направлении следующим образом:

$ ls -id lib
11666186 lib

$ find -inum 11666186 -exec stat -c "%h" {} +
3

Ссылки

4
30.01.2019, 00:11
2 ответа

Вы можете проверить, умер ли $pidвот так:

while kill -0 $pid >/dev/null; do
    # $pid is still alive
done

# $pid is dead or you lack permissions to send signals to it
3
27.01.2020, 20:54

Если ваша оболочка dash/ busybox, ksh93или zsh, вы можете установить ловушку наSIGCHLD:

#! /bin/sh
trap exit CHLD
"$@" &
while read line; do :; done
kill $!
wait

Это завершится, как только завершится процесс "$@" &или readполучит EOF.

Но bashимеет неприятный readвстроенный -, который перезапускается на месте при прерывании сигналом, так что нужно что-то более громоздкое. Вы можете настроить так, чтобы фоновый процесс отправлял завершающий сигнал своему родителю при выходе:

#! /bin/sh
{ "$@"; kill $$; } &
while read line; do :; done
pkill -P $!
kill $!
wait

При этом придется тратить еще один процесс на ожидание команды "$@"и использовать селектор-P(parent pid )для pkill, поскольку $!больше не относится к команде "$@", а своему родителю. Дополнительный kill $!по-прежнему необходим на тот случай, если "$@"окажется встроенным -. Обратите внимание, что в сценариях нет управления заданиями; все процессы (, включая запущенные с помощью &), выполняются в одной группе процессов.

Вы можете использовать p/kill -KILLвезде, если сигнала TERMнедостаточно.

Другой, еще более неуклюжий обходной путь, который работает только с более новыми (>= 4.0 )версиями bash, заключается в использовании нестандартного-t(тайм-аута )параметра readи использовании того факта, что readвернет 1 по EOFи статус> 128 по тайм-ауту:

#! /bin/bash
"$@" &
while :; do
        read -t 1 line
        case $? in
        0)      ;;
        1)      kill $!; wait; exit;;
        *)      kill -0 $! || exit;;
        esac
done 2>/dev/null

Похоже, это работает и с mksh.

1
27.01.2020, 20:54

Теги

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