Как использовать команду чтения в Bash? - PullRequest
52 голосов
/ 06 октября 2011

Когда я пытаюсь использовать команду read в Bash, вот так:

echo hello | read str
echo $str

Ничего не повторяется, хотя я думаю, что str должен содержать строку hello. Кто-нибудь может помочь мне разобраться в этом поведении?

Ответы [ 8 ]

56 голосов
/ 06 октября 2011

read в вашей команде скрипта в порядке.Однако вы выполняете его в конвейере, что означает, что он находится в подоболочке, поэтому переменные, которые он читает, не видны в родительской оболочке.Вы также можете либо

  • переместить остальную часть сценария в подоболочку:

    echo hello | { read str
      echo $str
    }
    
  • или использовать подстановку команд, чтобы получить значениепеременной из подоболочки

    str=$(echo hello)
    echo $str
    

    или чуть более сложный пример (захват 2-го элемента ls)

    str=$(ls | { read a; read a; echo $a; })
    echo $str
    
38 голосов
/ 06 октября 2011

Другие альтернативы bash, не включающие подоболочку:

read str <<END             # here-doc
hello
END

read str <<< "hello"       # here-string

read str < <(echo hello)   # process substitution
8 голосов
/ 06 октября 2011

Типичное использование может выглядеть следующим образом:

i=0
echo -e "hello1\nhello2\nhello3" | while read str ; do
    echo "$((++i)): $str"
done

и вывод

1: hello1
2: hello2
3: hello3
3 голосов
/ 06 октября 2011

Значение исчезает, поскольку команда чтения запускается в отдельной подоболочке: Bash FAQ 24

2 голосов
/ 04 апреля 2014

Чтобы поместить мои два цента здесь: на KSH, read при условии, что переменная будет работать, потому что согласно документации IBM AIX , KSH read делает влияет на текущую среду оболочки:

Установка переменных оболочки с помощью команды read влияет на текущую среду выполнения оболочки.

Это просто привело кя потратил немало минут на то, чтобы понять, почему однострочный, заканчивающийся read, который я использовал миллион раз до этого в AIX, не работал на Linux ... это потому, что KSH сохраняет данные в текущей среде, а BASH - нет.«т!

0 голосов
/ 19 июля 2017

Я действительно использую только чтение с "while" и циклом do:

echo "This is NOT a test." | while read -r a b c theRest; do  
echo "$a" "$b" "$theRest"; done  

Это тест.
Что бы это ни стоило, я видел рекомендацию всегда использовать -r с командой чтения в bash.

0 голосов
/ 05 апреля 2014

Другой альтернативой является использование функции printf.

printf -v str 'hello'

Кроме того, эта конструкция в сочетании с использованием одинарных кавычек, где это уместно, помогает избежать многократных проблем подоболочек и других форм интерполяционного цитирования.

0 голосов
/ 06 октября 2011

Тебе нужна труба?

echo -ne "$MENU"
read NUMBER
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...