我在 bash 脚本中有一个此处文档。我想从中读取一个值:
su myUser<<SESSION
set -x
echo -n "Enter your name and press [ENTER]: "
read name
echo "the name is $name"
SESSION
但是,当我从另一个用户启动此脚本时,bash 不会停止等待输入并忽略该read
命令。
有任何想法吗 ?
答案1
饰演 L·斯科特·约翰逊正确找到,read
从标准输入读取。运行的shell 中的标准输入su
连接到此处文档,因此read
读取文字字符串echo "the name is "
(请注意,由于此处文档未加引号,因此$name
已扩展为空字符串,或者扩展为它在调用 shell)。
这是同样的事情,但带有引用的此处文档,并$name
再次输出额外的行:
su username <<'SESSION'
set -x
echo -n "Enter your name and press [ENTER]: "
read name
echo "the name is $name"
echo "What I read was $name"
SESSION
输出将是
Password:
+ echo -n Enter your name and press [ENTER]:
Enter your name and press [ENTER]: + read name
+ echo What I read was echo "the name is $name"
What I read was echo "the name is $name"
要正确执行此操作,您不能read
从标准输入读取。相反,打开一个新的文件描述符作为标准输入的副本,并read
从中读取:
su username 3<&0 <<'SESSION'
set -x
echo -n "Enter your name and press [ENTER]: "
read name <&3
echo "the name is $name"
SESSION
如果对方用户的shell是bash
或ksh
,则read name <&3
可以替换为read -u3 name
。
但请注意,您不能期望name
在 shell 调用中设置变量,su
因为子 shell 无法修改父 shell 的环境(变量等)。
答案2
它不会忽略读命令;它执行它并读取标准输入。然后echo "the name is $name
(从标准输入)读取该行并将其分配给 $name。
su myUser<<SESSION
set -x
echo -n \"Enter your name and press [ENTER]: \"
read name
someUser
echo \"the name is \$name\"
SESSION
输出:
+ echo -n '"Enter' your name and press '[ENTER]:' '"'
-n "Enter your name and press [ENTER]: "
+ read name
+ echo '"the' name is 'someUser"'
"the name is someUser"