shell cat<<EOF 变量自动解析问题
1. 使用 cat<<EOF>
时,脚本中的变量被解析了
使用如下shell安装node时,一直提示 command not found
wget https://mirrors.huaweicloud.com/nodejs/latest-v8.x/node-v8.16.0-linux-x64.tar.gz
tar zxvf node-v8.16.0.tar.gz -C /usr/local
cd /usr/local/
mv node* node
cat <<EOF> /etc/profile.d/node.sh
export NODE_HOME=/usr/local/node
export PATH=$NODE_HOME/bin:$PATH
EOF
source /etc/profile
去检查 node.sh 才发现变量被解析了。
#cat /etc/profile.d/node.sh
export NODE_HOME=/usr/local/node
export PATH=/usr/local/node/bin:/usr/local/node/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/redis/bin/:/root/bin
两个解决办法:
- 1) 加转义字符,适用于变量少的情况
[root@elk ~]# cat <<EOF> /etc/profile.d/node.sh
> export NODE_HOME=/usr/local/node
> export PATH=\$NODE_HOME/bin:\$PATH
> EOF
[root@elk ~]# cat /etc/profile.d/node.sh
export NODE_HOME=/usr/local/node
export PATH=$NODE_HOME/bin:$PATH
- 2) EOF 加反斜杠,或用单引号、双引号包围 。适用变量多的情况
[root@elk ~]# cat <<'EOF'> /etc/profile.d/node.sh
> export NODE_HOME=/usr/local/node
> export PATH=$NODE_HOME/bin:$PATH
> EOF
[root@elk ~]# cat /etc/profile.d/node.sh
export NODE_HOME=/usr/local/node
export PATH=$NODE_HOME/bin:$PATH
2. 对比 cat<<EOF>
和 cat<<- EOF>
的区别
两个都是获取stdin,并在EOF处结束stdin,输出stdout。
但是 <<-
是什么意思呢?
先来看man中的说明:
If the redirection operator is <<-, then all leading tab characters are stripped from input lines and the line containing delimiter.
翻译过来的意思就是:如果重定向的操作符是 <<-
,那么分界符 EOF
所在行的开头部分的制表符(Tab)都将被去除。
这可以解决由于脚本中的自然缩进产生的制表符。通俗一点的解释:
在我们使用 cat <<EOF
时,我们输入完成后,需要在一个新的一行输入EOF
结束 stdin 的输入。EOF
必须顶行写,前面不能用制表符或者空格。
比如,下面的语句就不会出错:
cat <<EOF
Hello,world!
EOF
如果结束分解符 EOF
前有制表符或者空格,则 EOF
不会被当做结束分界符,只会继续被当做stdin来输入。
而 <<-
就是为了解决这一问题:
cat <<-EOF
Hello,world!
EOF
上面的写法,虽然最后的 EOF
前面有多个制表符和空格,但仍然会被当做结束分界符,表示 stdin 的结束。
这就是 <<
和 <<-
的区别。