Когда я пытаюсь использовать команду read
в Bash следующим образом:
echo hello | read str
echo $str
Ничего не повторилось, хотя я думаю, что str
должен содержать строку hello
. Может ли кто-нибудь помочь мне понять это поведение?
Когда я пытаюсь использовать команду read
в Bash следующим образом:
echo hello | read str
echo $str
Ничего не повторилось, хотя я думаю, что str
должен содержать строку hello
. Может ли кто-нибудь помочь мне понять это поведение?
read
в вашей команде script в порядке. Однако вы выполняете его в конвейере, что означает, что он находится в подоболочке, поэтому переменные, которые он читает, не видны в родительской оболочке. Вы можете либо
также перемещаем остальную часть script в подоболочку:
echo hello | { read str
echo $str
}
или используйте подстановку команд, чтобы получить значение переменной из подоболочки
str=$(echo hello)
echo $str
или несколько более сложный пример (захват второго элемента ls)
str=$(ls | { read a; read a; echo $a; })
echo $str
Другие альтернативы bash, которые не включают подоболочку:
read str <<END # here-doc
hello
END
read str <<< "hello" # here-string
read str < <(echo hello) # process substitution
Типичное использование может выглядеть так:
i=0
echo -e "hello1\nhello2\nhello3" | while read str ; do
echo "$((++i)): $str"
done
и вывод
1: hello1
2: hello2
3: hello3
Значение исчезает, так как команда чтения запускается в отдельной подоболочке: Bash FAQ 24
Чтобы разместить мои два цента здесь: на KSH, read
ing, как и на переменную, будет работать, потому что согласно документации IBM AIX, KSH read
влияет на текущую среду оболочки:
Настройка переменных оболочки с помощью команды чтения влияет на текущую среду выполнения оболочки.
Это привело к тому, что я потратил немало минут на то, чтобы выяснить, почему однострочный финал с read
, который я использовал миллион раз, прежде чем на AIX не работал в Linux... это потому, что KSH сохраняет к текущей среде и BASH не работает!
Я действительно использую только чтение с "while" и do loop:
echo "This is NOT a test." | while read -r a b c theRest; do
echo "$a" "$b" "$theRest"; done
Это тест.
Для чего это стоит, я видел рекомендацию всегда использовать -r с командой чтения в bash.
Другой альтернативой является использование функции printf.
printf -v str 'hello'
Кроме того, эта конструкция, в сочетании с использованием одинарных кавычек, где это уместно, помогает избежать проблем с несколькими побегами подоболочек и других форм интерполяционного цитирования.
Вам нужна труба?
echo -ne "$MENU"
read NUMBER