在编写 shell 脚本时,你可能需要将多行文本或代码块传递给交互式命令,例如 tee 、cat 或 sftp.
在 Bash 和其他 shell(如 Zsh)中,Here-document
(Heredoc
) 是一种重定向类型,允许您将多行输入传递给命令。
HereDoc 的语法如下:
[COMMAND] <<[-] 'DELIMITER'HERE-DOCUMENT
DELIMITER
<<
和结束符。EOF
和 END
<<-
,将导致输出时删除heredoc内行首的所有\t
, 但不会删除空格。Heredoc 经常和 cat 命令一起使用。
cat << EOF
The current working directory is: $PWD
You are logged in as: $(whoami)
EOF
Output就是:
The current working directory is: /home/abc
You are logged in as: abc
那么如果把结束符用双引号括起来会怎么样呢? 那么,环境变量就不会被替换,而命令也不会被执行。
$ cat << "EOF"
The current working directory is: $PWD
You are logged in as: $(whoami)
EOFThe current working directory is: $PWD
You are logged in as: $(whoami)
<<
后加上减号-
则在输出时将Heredoc块内的行首的所有\t
消除注意,如果以空格开头,则空格不会被消除;只会消除行开头的\t
,哪怕是多个\t
,都会被消除。
cat << EOFLine without a leading tab.
EOFLine without a leading tab.
cat << EOF > file.txt
The current working directory is: $PWD
You are logged in as: $(whoami)
EOFcat file.txt
The current working directory is: /home/abc
You are logged in as: abc
sed
下面的例子将单词中的o
替换成a
cat <<'EOF' | sed 's/o/a/g'
Hellooo
Woorld
EOFHellaaa
Waarld
也可以先管道给sed
,再输出到文件。
cat <<'EOF' | sed 's/l/e/g' > file.txt
Hello
World
EOFcat file.txt
Heeeo
Wored
要通过ssh在远程系统上执行多个命令,Heredoc是最方便和最简单的方式之一。
ssh -T def@server_side.com << EOF
echo "The current local working directory is: $PWD"
echo "The current remote working directory is: \$PWD"
EOF
Copy
The current local working directory is: /home/abc
The current remote working directory is: /home/def
注意,上面第二个$PWD
前面需要转义,因为此时想取远程机器的PWD变量。
以下是一个shell脚本的内容。这个脚本能够接收用户的输入作为密码,然后以此访问一个远程机器。
#!/usr/bin/shecho -n "Please input password for remote system:"
read -s password/usr/bin/expect <<- EOF | tee /home/abc/123.txt
spawn ssh abc@some_host ls -l
set timeout 5
expect "abc@some_host's password: "
send -- "$password\r"
expect eof
EOF
(END)