![Невозможно получить идентификатор процесса из $! в bash 3.2.57](https://rvso.com/image/170647/%D0%9D%D0%B5%D0%B2%D0%BE%D0%B7%D0%BC%D0%BE%D0%B6%D0%BD%D0%BE%20%D0%BF%D0%BE%D0%BB%D1%83%D1%87%D0%B8%D1%82%D1%8C%20%D0%B8%D0%B4%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%82%D0%BE%D1%80%20%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%D0%B0%20%D0%B8%D0%B7%20%24!%20%D0%B2%20bash%203.2.57.png)
На моем удаленном сервере с bash 4.2.46 я могу сделать это:
$ sleep 100 & pid=$!; echo "$pid"; wait "$pid"
[3] 7646
7646
Однако на моем Mac с bash 3.2.57 это не работает:
$ sleep 100 & pid=$!; echo "$pid"; wait "$pid"
-bash: !: event not found
Что происходит? Каким-то образом я bash
годами пользовался macOS и никогда не сталкивался с этой проблемой... но клянусь, я запускал множество программ оболочки, которые используют именно этот $!
метод для получения идентификатора фонового процесса, и ни разу не видел, чтобы они ломались.
решение1
Это !
символ-триггер дляистория расширение, включен в интерактивных оболочках по умолчанию.
Я не думаю, что это сделает что-то полезное pid=$!;
в вашем случае или в echo "$!"
. Как вы можете видеть из сообщения об ошибке, он пытается использовать пустую строку для поиска, а не что-то вроде !foo
поиска foo
. Более новые версии Bash более разумны в этом $!
или "!"
не вызывают его, но 3.2 немного глуповат с этим.
Кажется, работает pid=$! ;
, с пробелом перед точкой с запятой. Или вы можете просто отключить расширение истории с помощью set +H
. (Обратите внимание, что"$!"
не делаетработа в 3.2.)