У меня есть UNIX-программа черного ящика, используемая в оболочке Bash, которая читает столбцы данных из stdin, обрабатывает их (применяя эффект сглаживания), а затем выводит в stdout. Я использую его по каналам UNIX, как
generate | smooth | plot
Для большего сглаживания я могу повторить сглаживание, чтобы оно вызывалось из командной строки Bash как
generate | smooth | smooth | plot
или даже
generate | smooth | smooth | smooth | smooth | smooth | smooth | smooth | smooth | smooth | smooth | plot
Это становится неприятным. Я хотел бы сделать обертку Bash, чтобы иметь возможность передавать smooth
и передавать свои выходные данные обратно в новый экземпляр smooth
произвольное число раз, что-то вроде
generate | newsmooth 5 | plot
вместо того
generate | smooth | smooth | smooth | smooth | smooth | plot
Моей первой попыткой был сценарий Bash, который генерировал временные файлы в текущем каталоге и удалял их, но это выглядело ужасно, когда я не находился в каталоге с доступом для записи, а также оставлял файлы мусора при прерывании.
У программы нет аргументов smooth
.
Есть ли более элегантный способ «обернуть» такую программу для параметризации количества вызовов?
источник
Ответы:
Вы могли бы обернуть это в рекурсивную функцию:
Вы бы использовали это как
что будет эквивалентно
источник
Если вы можете позволить себе вводить столько запятых, сколько
smooth
команд вам нужно, вы можете воспользоваться расширением скобок, разделенным запятыми.TL; DR
Вся командная строка для вашего примера:
Замечания:
smooth |
|
раньше,plot
потому что это включено в последнююsmooth |
строку, созданную расширением скобкиsmooth
, если вы можете правильно их включить в заключенную в кавычки фиксированную часть, которая предшествует открытой фигурной скобке; в любом случае помните, что вы предоставляете их для всех повторений командыКак это устроено
Разделенное запятыми расширение скобок позволяет динамически создавать строки, каждая из которых состоит из указанной фиксированной части плюс указанные переменные части. Он производит столько строк, сколько указано переменных частей, например,
a{b,c,d}
производитab ac ad
.Небольшая хитрость заключается в том, что если вы скорее составите список пустых переменных частей, то есть только с запятыми внутри фигурных скобок, расширение скобок будет просто производить копии только фиксированной части. Например:
будет производить:
Обратите внимание, что 4 запятые производит 5
smooth
строк. Вот так работает этот Brace Expansion: он выдает в строку столько запятых плюс один.Конечно, в вашем случае вам также нужно
|
разделить каждый из нихsmooth
, поэтому просто добавьте его в фиксированную часть, но позаботьтесь о том, чтобы его правильно процитировать, чтобы оболочка не интерпретировала его сразу. То есть:будет производить:
Позаботьтесь о том, чтобы всегда размещать фиксированную часть непосредственно рядом с открытой скобой, то есть без пробелов между
'
и{
.(Обратите также внимание, что для формирования фиксированной части вы также можете использовать двойные кавычки вместо одинарных кавычек, если вам нужно расширить переменные оболочки в фиксированной части. Просто позаботьтесь о дополнительном экранировании, которое требуется при появлении некоторых специальных символов оболочки внутри строки в двойных кавычках).
На этом этапе вам нужно
eval
применить к этой строке, чтобы оболочка окончательно интерпретировала ее как конвейерную команду, которой она должна быть.Таким образом, чтобы подвести итог всего этого, вся командная строка для вашего примера будет выглядеть так:
источник
eval
когда вы предоставляете для оценки ненадежные, необработанные строки, то есть при использовании с переменными, которые могут содержать «неизвестный» контент, такой как случай, который вы связали. С другой стороны,eval
это также может быть очень удобно для быстрого «слежения» за командами, особенно при использовании в командной строке, как, например, в данном случае, гдеeval
ввод будет только литеральной строкой, набираемой вручную пользователем в человекeval str
что-то претенциозным и глупым, как. /dev/stdin <<<str
. Это не только произведет впечатление на дураков, но и удержит @CharlesDuffy у вас за спиной ;-)