Вывод трубы на функцию bash
У меня есть простая функция в bash script, и я хотел бы передать ему stdout в качестве ввода.
jc_hms(){
printf "$1"
}
Я хотел бы использовать его таким образом.
var=`echo "teststring" | jc_hms`
Конечно, я использовал избыточные функции echo и printf, чтобы упростить вопрос, но вы поняли эту идею. Прямо сейчас я получаю ошибку "не найден", которая, как я полагаю, означает, что мое разграничение параметров неверно (часть "$ 1" ). Любые предложения?
Первоначально функция jc_hms использовалась следующим образом:
echo `jc_hms "teststring"` > //dev/tts/0
но сначала я хочу сохранить результаты в переменной для дальнейшей обработки, прежде чем отправлять ее на последовательный порт.
EDIT:
Поэтому, чтобы уточнить, я НЕ пытаюсь печатать материал на последовательном порту, я хотел бы взаимодействовать с моими функциями bash, если "|" характер трубы, и мне интересно, возможно ли это.
EDIT: Хорошо, здесь полная функция.
jc_hms(){
hr=$(($1 / 3600))
min=$(($1 / 60))
sec=$(($1 % 60))
printf "$hs:%02d:%02d" $min $sec
}
Я использую функцию для формирования строки, которая соответствует этой строке кода
songplaytime=`echo $songtime | awk '{print S1 }'`
printstring="`jc_hms $songplaytime`" #store resulting string in printstring
Где $songtime - это строка, выраженная как "общее время воспроизведения", ограниченное пробелом.
Мне жаль, что я не могу просто сделать это в одной строке и передать его после awk
printstring=`echo $songtime | awk '{print S1 }' | jc_hms`
.
Ответы
Ответ 1
Чтобы ответить на ваш реальный вопрос, когда функция оболочки находится на приемном конце канала, стандартный ввод читается первой командой, выполняемой внутри функции. Поскольку printf
- первая и единственная команда в вашей функции, стандартный ввод игнорируется. Есть несколько способов обойти это, включая использование встроенного read
для чтения стандартного ввода в переменную, которая может быть передана в printf
:
jc_hms () {
read foo
hr=$(($foo / 3600))
min=$(($foo / 60))
sec=$(($foo % 60))
printf "%d:%02d:%02d" "$hr" "$min" "$sec"
}
Однако, поскольку ваша потребность в конвейере зависит от вашей предполагаемой необходимости использовать awk
, позвольте мне предложить следующую альтернативу:
printstring=$( jc_hms $songtime )
Поскольку songtime
состоит из пары чисел, разделенных songtime
, оболочка выполняет разбиение слов по значению songtime
, а jc_hms
видит два отдельных параметра. Это не требует никаких изменений в определении jc_hms
, и нет необходимости jc_hms
что-либо в него через стандартный ввод.
Если у вас все еще есть другая причина, по которой jc_hms
читает стандартный ввод, сообщите нам об этом.
Ответ 2
Вы не можете напрямую передать материал в функцию bash, но вы можете использовать read
, чтобы вытащить ее вместо:
jc_hms(){
while read data; do
printf "%s" "$data"
done
}
должен быть тем, что вы хотите
Ответ 3
1) Я знаю, что это довольно старый пост
2) Мне нравится большинство ответов здесь
Однако я нашел этот пост, потому что мне нужно было что-то подобное. В то время как все согласны с тем, что stdin - это то, что нужно использовать, то, что здесь отсутствует, является фактическое использование файла /dev/stdin.
Использование встроенного чтения заставляет эту функцию использоваться с канальным вводом, поэтому ее больше нельзя использовать обычным способом. Я думаю, что использование /dev/stdin - лучший способ решить эту проблему, поэтому я хотел добавить свои 2 цента для полноты.
Мое решение:
jc_hms() {
declare -i i=${1:-$(</dev/stdin)};
declare hr=$(($i/3600)) min=$(($i/60%60)) sec=$(($i%60));
printf "%02d:%02d:%02d\n" $hr $min $sec;
}
В действии:
[email protected]:pwd$ jc_hms 7800
02:10:00
[email protected]:pwd$ echo 7800 | jc_hms
02:10:00
Надеюсь, это поможет кому-то.
Счастливый взлом!
Ответ 4
Или вы также можете сделать это простым способом.
jc_hms() {
cat
}
Хотя все ответы до сих пор не учитывали тот факт, что это не то, что хотел OP (он заявил, что функция упрощена)
Ответ 5
Мне нравится user.friendly answer, используя встроенный синтаксис подстановки Bash
.
Здесь небольшая настройка, чтобы сделать его ответ более общим, например, для случаев с неопределенным количеством параметров:
function myfunc() {
declare MY_INPUT=${*:-$(</dev/stdin)}
for PARAM in $MY_INPUT; do
# do what needs to be done on each input value
done
}
Ответ 6
Хммм....
songplaytime=`echo $songtime | awk '{print S1 }'`
printstring="`jc_hms $songplaytime`" #store resulting string in printstring
если вы все равно звоните awk, почему бы не использовать его?
printstring=`TZ=UTC gawk -vT=$songplaytime 'BEGIN{print strftime("%T",T)}'`
Я предполагаю, что вы используете Gnu Awk, который является лучшим, а также бесплатным; это будет работать в общих дистрибутивах Linux, которые не обязательно используют последний gawk. Самые последние версии gawk позволят вам указать UTC в качестве третьего параметра функции strftime().