linux下划线后面加变量名,Shell中下划线_与变量的关系

本文通过一个shell脚本示例,探讨了在Linux下,下划线后面接变量名可能导致的解析问题。解释了为何使用短横线作为分隔符时文件命名正常,而使用下划线时可能会被解释为新的变量名。建议使用大括号或者转义字符来避免歧义,提高脚本的可读性和稳定性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个shell脚本根据日期和时间自动备份数据数据库的时候遇到一个问题$ vi /u01/app/bak/bin/public_serbak.sh

#!/bin/sh

export ORACLE_SID=orcl

export ORACLE_BASE=/u01/app/oracle

export ORACLE_HOME=$ORACLE_BASE/product/11.2.0/dbhome_1

export PATH=$ORACLE_HOME/bin:$PATH:/sbin/

export  LANG NLS_LANG='SIMPLIFIED CHINESE_CHINA.AL32UTF8'

timedate=$(date +%Y%m%d%H%M%S)

bakdbname=public_ser

bakdbpasswd=123

dumpbame=public_ser

bakdbhome=/u01/app/bak

1、expdp $bakdbname/$bakdbpasswd directory=backDir dumpfile=$dumpbame_$timedate.dmp logfile=$bakdbname_$timedate.log

cd $bakdbhome

zip -r $dumpbame_$timedate.zip "$dumpbame_$timedate.dmp $bakdbname_$timedate.log

2、expdp $bakdbname/$bakdbpasswd directory=backDir dumpfile=$dumpbame"_"$timedate.dmp logfile=$bakdbname_$timedate.log

cd $bakdbhome

zip -r $dumpbame"_"$timedate.zip $dumpbame"_"$timedate.dmp $bakdbname"_"$timedate.log

3、expdp $bakdbname/$bakdbpasswd directory=backDir dumpfile="$dumpbame"_"$timedate".dmp logfile="$bakdbname"_"$timedate".log

cd $bakdbhome

zip -r "$dumpbame"_"$timedate".zip "$dumpbame"_"$timedate".dmp "$bakdbname"_"$timedate".log

4、expdp $bakdbname/$bakdbpasswd directory=backDir dumpfile=${dumpbame}_${timedate}.dmp logfile=${bakdbname}_${timedate}.log

cd $bakdbhome

zip -r ${dumpbame}_${timedate}.zip ${dumpbame}_${timedate}.dmp ${bakdbname}_${timedate}.log

输出的四个文件:

20180815125435.dmp

public_ser_20180815125435.dmp

public_ser_20180815125435.dmp

public_ser_20180815125435.dmp

不是应该四个都一样么,都是dumpbame_timedate的格式吗?

用短横线:#!/bin/sh

export ORACLE_SID=orcl

export ORACLE_BASE=/u01/app/oracle

export ORACLE_HOME=$ORACLE_BASE/product/11.2.0/dbhome_1

export PATH=$ORACLE_HOME/bin:$PATH:/sbin/

export  LANG NLS_LANG='SIMPLIFIED CHINESE_CHINA.AL32UTF8'

timedate=$(date +%Y%m%d%H%M%S)

bakdbname=public_ser

bakdbpasswd=123

dumpbame=public_ser

bakdbhome=/u01/app/bak

expdp $bakdbname/$bakdbpasswd directory=backDir dumpfile=$dumpbame-$timedate.dmp logfile=$bakdbname-$timedate.log

cd $bakdbhome

zip -r $dumpbame-$timedate.zip $dumpbame-$timedate.dmp $bakdbname-$timedate.log

find $bakdbhome/*.log -mtime +10 -exec rm -rf {} \;

find $bakdbhome/*.zip -mtime +10 -exec rm -rf {} \;

find $bakdbhome/*.dmp -exec rm -rf {} \;

输出的文件为:

public_ser-20180815125435.dmp

public_ser-20180815125435.log

public_ser-20180815125435.zip

如果自动命名的文件的分隔符用短横线就没有问题,为什么会这样呢。

说明:

shell变量名后面要跟如下内容:非小写字符串(包括大小字符串)、数字或下划线,要么用转义字符“\”或者变量名用大括号。否则就会向本例中shell试图使用filename_作为变量名。除非出现$filename_已经存在的偶然情况,否则该语句不会打印任何内容(为null或空字符串),这就是第一次为什么输出的是文件 20130329的原因。

在shell中,取一个变量值的方法$varname的语法实际上是常用语法${varname}的简写形式,不管是避免歧义,还是增加可读性,变量加大括号都是一个很好的习惯,不要偷懒不加哟。

换成下划线:$ vi /u01/app/bak/bin/public_serbak.sh

#!/bin/sh

export ORACLE_SID=orcl

export ORACLE_BASE=/u01/app/oracle

export ORACLE_HOME=$ORACLE_BASE/product/11.2.0/dbhome_1

export PATH=$ORACLE_HOME/bin:$PATH:/sbin/

export  LANG NLS_LANG='SIMPLIFIED CHINESE_CHINA.AL32UTF8'

timedate=$(date +%Y%m%d%H%M%S)

bakdbname=public_ser

bakdbpasswd=123

dumpbame=public_ser

bakdbhome=/u01/app/bak

expdp $bakdbname/$bakdbpasswd directory=backDir dumpfile=$dumpbame"_"$timedate.dmp logfile=$bakdbname"_"$timedate.log

cd $bakdbhome

zip -r $dumpbame"_"$timedate.zip $dumpbame"_"$timedate.dmp $bakdbname"_"$timedate.log

find $bakdbhome/*.log -mtime +10 -exec rm -rf {} \;

find $bakdbhome/*.zip -mtime +10 -exec rm -rf {} \;

find $bakdbhome/*.dmp -exec rm -rf {} \;

简易的例子:[root@Linux mybash]# a=a

[root@Linux mybash]# b=b

[root@Linux mybash]# echo $a$b

ab

[root@Linux mybash]# echo $a_$b

b

[root@Linux mybash]# echo $a\_$b

a_b

[root@Linux mybash]# echo ${a}_${b}   #推荐方法

a_b

[root@Linux mybash]# echo "$a"_"$b"

a_b

[root@Linux mybash]# echo $a"_"$b

a_b

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值