Как использовать команду read в Bash?

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

echo hello | read str
echo $str

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

8 ответов


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

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

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

    str=$(echo hello)
    echo $str
    

    или немного более сложный пример (Хватая 2-й элемент 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

значение исчезает, так как команда read выполняется в отдельной подрешетке: bash FAQ 24


чтобы положить мои два цента здесь: на KSH,reading как к переменной будет работа, потому что согласно документация IBM AIX, КШ-х read тут влияет на текущую среду оболочки:

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

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


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

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

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


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

printf -v str 'hello'

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


вам нужна труба?

echo -ne "$MENU"
read NUMBER