为何ls -p在bash命令行与脚本中的输出结果存在差异?
bash脚本中
ls -ldp输出目录链接无尾斜杠的问题解决 现象描述
在Ubuntu GNU bash 5.1.16环境下:
- 交互式命令行执行
ls -ldp /var/www/cgi-bin/PLACENAMES,输出带尾斜杠:/var/www/cgi-bin/PLACENAMES -> PLACENAMES-BIGSUR/
- 但在bash脚本中执行相同命令(已尝试修改shebang、指定ls绝对路径),输出无尾斜杠:
lrwxrwxrwx 1 jack jack 17 Jan 17 2015 /var/www/cgi-bin/PLACENAMES -> PLACENAMES-BIGSUR
脚本内容及执行输出(来自set -vx):
!#/usr/bin/bash set -vx /usr/bin/ls -lpd /var/www/cgi-bin/PLACENAMES
347 test.ls-p.sh /usr/bin/ls -ldp /var/www/cgi-bin/PLACENAMES 3 /usr/bin/ls -ldp /var/www/cgi-bin/PLACENAMES lrwxrwxrwx 1 jack jack 17 Jan 17 2015 /var/www/cgi-bin/PLACENAMES -> PLACENAMES-BIGSUR
环境仅存在LS_COLORS变量,需求是在脚本中获取带尾斜杠的输出。
解决方法
方法1:检查目标是否为目录,手动添加斜杠
通过判断链接指向的目标是否为目录,用sed修改输出:
link="/var/www/cgi-bin/PLACENAMES" ls_result=$(/usr/bin/ls -ldp "$link") if [ -d "$link" ]; then echo "$ls_result" | sed 's/-> \(.*\)$/-> \1\//' else echo "$ls_result" fi
方法2:用readlink获取目标后拼接输出
先获取链接目标,再替换ls输出中的目标部分:
link="/var/www/cgi-bin/PLACENAMES" target=$(readlink "$link") # 若链接指向目录则加斜杠 [ -d "$link" ] && target="$target/" # 替换ls输出里的目标内容 /usr/bin/ls -ld "$link" | sed "s/-> .*$/-> $target/"
方法3:强制ls开启颜色输出后清理转义码
利用ls在颜色模式下会为目录添加斜杠的特性,开启颜色后去掉转义字符:
/usr/bin/ls -ldp --color=always /var/www/cgi-bin/PLACENAMES | sed -r 's/\x1B\[[0-9;]*[mK]//g'
原因说明
ls的输出行为会根据是否处于交互式终端环境调整:交互式下会配合LS_COLORS为目录添加尾斜杠做视觉区分;非交互式脚本环境中,ls默认关闭格式美化,即使使用-p参数,也可能不会输出尾斜杠。
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

