Operation

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 的结束。
这就是 <<<<- 的区别。

参考1(cat EOF变量被解析)
参考2 (cat<<EOF> 和 cat<< - EOF> 的区别)

留言

您的电子邮箱地址不会被公开。