Bash变量存路径被识别为系统路径而非字符串的问题求助
问题分析与解决方案
嘿,我来帮你捋清楚这个问题出在哪,以及怎么解决~
错误原因
你现在的写法里,cut -d/ -f2 $a是把$a当成文件名传给了cut命令——cut默认是读取文件内容来切割的,所以它会尝试打开./this/is/a/path/some.log这个文件,而不是把这个字符串本身作为输入处理。这就是为什么会报Device or resource busy的错:VMware的日志文件可能正被系统占用,cut没法读取它。
正确的解决方法
方法1:把字符串通过管道/Here-String传给cut
你需要把$a的内容作为cut的输入,而不是文件名。可以用echo配合管道,或者更高效的Here-String写法:
for a in $(find -name vmware.log); do # 管道写法 cutpath=$(echo "$a" | cut -d/ -f2) # 或者Here-String写法(更高效,少启动一个echo进程) # cutpath=$(cut -d/ -f2 <<< "$a") echo "切割后的部分:$cutpath" done
注意一定要给$a加双引号,如果路径里包含空格、特殊字符,不加引号会被bash拆分,导致错误。
方法2:用Bash内置的参数展开(无需外部命令)
其实不用调用cut这个外部命令,Bash本身就有字符串处理能力,速度更快:
比如你要提取./this/is/a/path/some.log里的this(也就是第二个字段),可以这么写:
for a in $(find -name vmware.log); do # 先去掉开头的./ temp=${a#./} # 再提取第一个/之前的部分 cutpath=${temp%%/*} echo "切割后的部分:$cutpath" done
解释下这两个参数展开:
${var#pattern}:去掉变量开头匹配的最短模式,这里${a#./}就是删掉开头的./${var%%pattern}:去掉变量结尾匹配的最长模式,这里${temp%%/*}就是删掉第一个/及后面的所有内容
额外建议:更安全的遍历find结果方式
用for a in $(find ...)遍历有个隐患:如果文件名里包含空格、换行符或者特殊字符,bash会把它们拆分成多个变量。更稳妥的方式是用while read循环配合find -print0:
find . -name vmware.log -print0 | while IFS= read -r -d '' a; do # 这里用上面任意一种方法处理$a cutpath=$(cut -d/ -f2 <<< "$a") echo "处理路径:$a,切割结果:$cutpath" done
-print0让find用null字符分隔结果,read -d ''让read以null为分隔符,这样就能完美处理所有特殊文件名。
内容的提问来源于stack exchange,提问作者BamBam
相关产品推荐
相关产品推荐

