поведение zsh немного отличается здесь, чем большинство других оболочек. Другие оболочки, как удар, пытаются развернуть подстановочные знаки. Если они не могут расшириться ни до чего, что они передают литеральную строку (содержащий подстановочные знаки) к приложению вместо этого. Но zsh не делает этого (хорошо, существует опция для этого, чтобы сделать это или не). zsh распечатает ту ошибку и не выполнит команду. Можно переопределить это путем выхода из подстановочного знака, если Вы действительно хотите его, передал приложению. В этом случае Вы делаете, так как Вы хотите, чтобы другая оболочка стороны развернула его. Так использование:
scp remotehost:\*.txt .
Это - на самом деле корректное поведение, с тех пор если бы у Вас действительно были некоторые локальные *.txt файлы в Вашем доме, то они были бы расширены до имени, которое не могло бы существовать на удаленном. Это не то, что Вы хотите.
В оболочках, которые их поддерживают (ksh, zsh, bash4), вы можете запустить программу
как совместный процесс .
ksh
: программа> вывод | &
zsh
, bash
: программа coproc> вывод
Это запускает программу
в фоновом режиме с его вводом, перенаправленным из канала
. Другой конец трубы открыт для оболочки.
Три преимущества этого подхода
программа
умирает (используйте wait
, чтобы дождаться этого) program
завершится (получите eof
на его стандартном вводе, если оболочка завершится). Я не думаю, что Вы собираетесь стать больше изящными, чем
tail -f /dev/null
то, что Вы уже предложили (предполагающий, что это использует inotify внутренне, не должно быть никакого опроса или пробуждений, таким образом, кроме того, чтобы быть нечетным взглядом, это должно быть достаточно).
Вам нужна утилита, которая будет работать неограниченно долго, сохранит ее stdout открытым, но ничего на самом деле не запишет в stdout и не выйдет, когда его stdin будет закрыт. Что-то как yes
на самом деле записи к stdout. cat
выйдет, когда его stdin закрывается (или независимо от того, что Вы перенаправляете в него, сделан). Я думаю sleep 1000000000d
мог бы работать, но tail
ясно лучше. Поле My Debian имеет a tailf
это сокращает команду немного.
Выбирание другого подхода, как насчет того, чтобы запустить программу под screen
?
tail -f /dev/null
приблизьтесь к лучшему и найдите это достаточно изящным также, так как использование команды соответствует намеченной цели вполне тесно.
– jw013
12.07.2012, 22:40
strace tail -f /dev/null
это кажется этим tail
использование inotify
и это пробуждения происходит в глупых случаях как sudo touch /dev/null
. Грустно, что, кажется, нет никакого лучшего решения... Интересно, который был бы правом syscall для использования для реализации лучшего решения.
– a3nm
12.07.2012, 22:59
pause
, но это не выставляется непосредственно интерфейсу оболочки.
– Gilles 'SO- stop being evil'
13.07.2012, 01:25
screen
, но это должно выполнить несколько случаев программы из сценария оболочки для тестирования, таким образом с помощью screen
немного излишества.
– a3nm
20.07.2012, 15:19
sleep 2147483647 | program > output &
Да, 2^31-1
конечное число, и оно не будет работать навсегда, но я дам Вам 1 000$, когда сон наконец испытает таймаут. (Подсказка: один из нас будет мертв к тому времени.)
sleep 2147483647d
...
– agc
04.06.2017, 19:14
Перенаправление /dev/zero
как стандартный вход!
program < /dev/zero > output &
бесконечность сна [112667] является самым ясным решением, о котором я знаю.
make
make install
modprobe r8192se_pci
Вы можете использовать [112668] бесконечность [112669], потому что [112670] сна [112671] принимает число с плавающей точкой [112672]*[112673], которое может быть [112674] десятичным [112675], [112676] шестнадцатеричным [112677], [112678] бесконечность [112679], или [112680] NaN[112681], согласно [112682] man strtod [112683].
* Это не является частью стандарта POSIX, так же как и [112684] хвост -f /dev/null[112685]. Однако он поддерживается в GNU coreutils (Linux) и BSD (используется на Mac) (очевидно, не поддерживается на более новых версиях Mac - см. комментарии)[112350].Вы можете создать двоичный файл, который делает именно это, с помощью:
$ echo 'int main(){ pause(); }' > pause.c; make pause
Вот еще одно предложение с использованием стандартных утилит Unix, чтобы «ничего не делать бесконечно» .
sh -c 'kill -STOP $$' | program > output
Запускает оболочку, которая немедленно отправляет SIGSTOP
, что приостанавливает процесс. Это используется как «вход» в вашу программу. Дополнением к SIGSTOP
является SIGCONT
, т.е. если вы знаете, что оболочка имеет PID 12345, вы можете kill -CONT 12345
, чтобы продолжить работу.
В Linux вы можете:
read x < /dev/fd/1 | program > output
В Linux, открыв / dev / fd / x, где x - дескриптор файла для записывающего конца канала, вы получите читающий конец канала, так что здесь то же самое как на стандартном вводе программы. Таким образом, read
никогда не вернется, потому что единственное, что может писать в этот канал, - это он сам, а read
ничего не выводит.
Он также будет работать во FreeBSD или Solaris, но по другой причине. Там открытие / dev / fd / 1 дает вам тот же ресурс, что и open на fd 1, как и следовало ожидать, и как и большинство систем, кроме Linux, так что записывающий конец канала. Однако во FreeBSD и Solaris каналы являются двунаправленными. Итак, пока программа
не записывает на свой стандартный ввод (ни одно приложение не делает), read
не получит ничего для чтения из этого направления канала.
В системах, где каналы не являются двунаправленными, чтение
, вероятно, завершится ошибкой при попытке чтения из файлового дескриптора, доступного только для записи. Также обратите внимание, что не во всех системах есть / dev / fd / x
.
Стефан Хазелас читать
решение работает и в Mac OS X, если fd чтения открывается на / dev / fd / 1
.
# using bash on Mac OS X
# -bash: /dev/fd/1: Permission denied
read x </dev/fd/1 | cat >/dev/null
echo ${PIPESTATUS[*]} # 1 0
exec 3<&- 3</dev/fd/1
read x 0<&3 | cat >/dev/null
echo ${PIPESTATUS[*]} # 0 0
Чтобы иметь возможность убить tail -f / dev / null
в сценарии (например, с помощью SIGINT), необходимо выполнить команду tail
и подождать
.
#!/bin/bash
# ctrl-c will kill tail and exit script
trap 'trap - INT; kill "$!"; exit' INT
exec tail -f /dev/null & wait $!