Вы можете использовать команду 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
Вы можете проверить, умер ли $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
Если ваша оболочка 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
.