Следующая ifnotemptyфункция передает свой ввод команде, переданной в качестве аргумента, за исключением того, что она ничего не делает, если ввод пуст. Используйте это, чтобы передать source --fooв sink --barписьменном виде source --foo | pipe_if_not_empty sink --bar.
Я ожидаю, что эта реализация будет работать на всех платформах POSIX / Unix, хотя, строго говоря, она не соответствует стандартам: она полагается на то, что она ddне читает больше, чем один байт, который, как ей говорят, читает на своем стандартном вводе.
Я думаю, head -c 1что будет подходящей заменой для dd bs=1 count=1 2>/dev/nullLinux.
С другой стороны, head -n 1это не подходит, потому что headобычно буферизует входные данные и может прочитать больше, чем одну строку, которую он выводит - а поскольку он читает из канала, лишние байты просто теряются.
read -r headи даже read -r -n 1 headздесь не подходят, потому что, если первый символ является новой headстрокой, будет установлена пустая строка, что делает невозможным различение пустого ввода и ввода, начинающегося с пустой строки.
Мы не можем просто написать, head=$(head -c 1)потому что, если первый символ является новой строкой, подстановка команд лишит последней новой строки, делая невозможным различение пустого ввода и ввода, начинающегося с пустой строки.
В Баше, KSH или Zsh, вы можете заменить catна </dev/stdinмикроскопическое прирост производительности.
Если вы не возражаете против сохранения всех промежуточных данных в памяти, то здесь есть несколько более простая реализация pipe_if_not_empty.
Вот немного более простая реализация со следующими предостережениями:
Данные, созданные источником, считаются пустыми, если и только если они состоят исключительно из символов новой строки. (Это может быть на самом деле желательно.)
Данные, поступающие в приемник, заканчиваются ровно одним символом новой строки, независимо от того, сколько новых строк заканчивается данными, созданными источником. (Это может быть проблемой.)
$ echo -e "\n\n"| xargs -r ls
$ # No output. ls did not run.
$ echo -e "\n\n1"| xargs -r ls
ls: cannot access 1:No such file or directory
Это просто, но это должно работать для вас. Если ваша «функция» отправит пустую строку или даже новую строку по конвейеру, xargs -r предотвратит переход к «другой функции».
Приведенная ниже функция пытается прочитать 1-й байт, и в случае успешного завершения выводит этот байт, а остальные - кошки. Должен быть эффективным и 100% портативным.
Эта функция не работает для меня, когда я бегу echo -en "\nX" | pipe_if_not_empty mail -s "Subject line here" foo@bar.com. Он считает, что lineи hereоба являются получателями электронной почты, а не токены в теме. Я должен уйти от "окружающего предмета, чтобы заставить его работать. Однако pipe_if_not_emptyфункция из принятого ответа работает для меня даже без побега.
kuzzooroo
2
По крайней мере, что-то вроде этого работает:
yourcommand | if [ $(wc -c) -gt "0" ]; then yourothercommand; fi
Обратите внимание, что приведенное выше будет рассматривать перевод строки и другие специальные символы в качестве вывода, поэтому пустая строка, переданная этому оператору if, будет считаться выводом. Просто увеличьте предел -gt, если ваш вывод обычно превышает 1 байт :)
Ответы:
Следующая
ifnotempty
функция передает свой ввод команде, переданной в качестве аргумента, за исключением того, что она ничего не делает, если ввод пуст. Используйте это, чтобы передатьsource --foo
вsink --bar
письменном видеsource --foo | pipe_if_not_empty sink --bar
.Дизайн заметки:
dd
не читает больше, чем один байт, который, как ей говорят, читает на своем стандартном вводе.head -c 1
что будет подходящей заменой дляdd bs=1 count=1 2>/dev/null
Linux.head -n 1
это не подходит, потому чтоhead
обычно буферизует входные данные и может прочитать больше, чем одну строку, которую он выводит - а поскольку он читает из канала, лишние байты просто теряются.read -r head
и дажеread -r -n 1 head
здесь не подходят, потому что, если первый символ является новойhead
строкой, будет установлена пустая строка, что делает невозможным различение пустого ввода и ввода, начинающегося с пустой строки.head=$(head -c 1)
потому что, если первый символ является новой строкой, подстановка команд лишит последней новой строки, делая невозможным различение пустого ввода и ввода, начинающегося с пустой строки.cat
на</dev/stdin
микроскопическое прирост производительности.Если вы не возражаете против сохранения всех промежуточных данных в памяти, то здесь есть несколько более простая реализация
pipe_if_not_empty
.Вот немного более простая реализация со следующими предостережениями:
Опять же, все данные хранятся в памяти.
источник
Это должно работать для вас
Пример
Это просто, но это должно работать для вас. Если ваша «функция» отправит пустую строку или даже новую строку по конвейеру, xargs -r предотвратит переход к «другой функции».
Ссылка на xargs: http://www.oreillynet.com/linux/cmd/cmd.csp?path=x/xargs
источник
ifne (1) из moreutils делает именно это. Moreutils доступен как пакет, по крайней мере, в Debian и Ubuntu, возможно, и в других дистрибутивах.
источник
Приведенная ниже функция пытается прочитать 1-й байт, и в случае успешного завершения выводит этот байт, а остальные - кошки. Должен быть эффективным и 100% портативным.
Тестовые случаи:
источник
echo -en "\nX" | pipe_if_not_empty mail -s "Subject line here" foo@bar.com
. Он считает, чтоline
иhere
оба являются получателями электронной почты, а не токены в теме. Я должен уйти от"
окружающего предмета, чтобы заставить его работать. Однакоpipe_if_not_empty
функция из принятого ответа работает для меня даже без побега.По крайней мере, что-то вроде этого работает:
yourcommand | if [ $(wc -c) -gt "0" ]; then yourothercommand; fi
Обратите внимание, что приведенное выше будет рассматривать перевод строки и другие специальные символы в качестве вывода, поэтому пустая строка, переданная этому оператору if, будет считаться выводом. Просто увеличьте предел -gt, если ваш вывод обычно превышает 1 байт :)
источник
yourothercommand
никогда не видит выводyourcommand
.Вместо
sender | receiver
:Или вы можете сделать его более универсальным, изменив его так, чтобы он принимал принимающую программу в качестве аргумента, как в ответе Жиля:
источник