#bash
#bash
Вопрос:
Я пытаюсь написать простой эквивалент input
функции Python в Bash.
Примером в скрипте Python может быть что-то вроде этого:
s = input('Please input something: ')
Я полагаю, что вызов эквивалента Bash будет выглядеть следующим образом:
s=$(input "Please input something: ")
Это реализация, которую я написал:
function input {
# $1 is the prompt passed as an argument; in my above example,
# it would be 'Please input something: '
printf "%s" "$1"
read in
echo "${in}"
return 0
}
При вызове s=$(input "Please enter something: ")
приглашение никогда не печатается; вместо этого скрипт Bash просто ожидает ввода пользователем, даже не отображая текст. Нажатие Enter, то есть не ввод, устанавливает s
само приглашение. Похоже, что происходит s
захват выходных данных из строки printf "%s" "$1"
, затем считывание входных данных, которые также отражаются обратно. Я также пытался явно направить приглашение на stdout
with printf "%s" "$1" >amp;1
, но безрезультатно.
Как я могу сначала распечатать приглашение, затем захватить ввод и передать его обратно вызывающей функции?
Комментарии:
1. Ответ Джонка правильный, но, тем не менее, чтобы ваше приглашение отправлялось в TTY без захвата, запишите его в stderr, а не в stdout, который также имеет удачное преимущество в том, что по умолчанию он не буферизован, тогда как когда stdout направляется в TTY, он по умолчанию буферизуется по строкам. Кстати, собственные подсказки оболочки также передаются в stderr.
Ответ №1:
Вам повезло. Она уже существует в виде read -p
.
read -p 'Please input something: ' s
На всякий случай неплохо IFS=
-r
также использовать and . IFS=
гарантирует сохранение начальных и конечных пробелов. -r
сохраняет обратную косую черту, поэтому n
не интерпретируется как перевод строки или \
не превращается в
.
IFS= read -rp 'Please input something: ' s
Что касается того, почему ваша функция не работает, это потому, что приглашение печатается в стандартный вывод, который фиксируется. Выведите в stderr, чтобы она отображалась.
input() {
printf "%s" "$1" >amp;2
read in
printf '%sn' "$in"
}
Тщательный сценарист будет использовать printf '%sn'
вместо echo
. Если пользователь вводит -n
или -e
вы хотите, чтобы они печатались, а не интерпретировались как параметры.