You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shell脚本中mv命令报错No such file or directory求助排查

解决 mv: cannot stat 'tmp': No such file or directory 错误 & 脚本优化

我帮你分析下脚本里的问题,这个错误主要是几个明确的问题点导致的,我们一步步来修复:

1. 直接触发错误的多余 mv 命令

看你脚本里这一行:

#Escaping and cleanup
mv tmp $currentFile

这一行前面没有任何生成tmp文件的操作,之前的sed命令都已经通过&& mv tmp $currentFile完成了临时文件的替换,所以这里的tmp根本不存在,执行这行必然报错。直接删掉这一行就能解决这个即时错误。

2. eval 使用不当导致的潜在 tmp 生成失败

你的SED_ARG变量里的引号嵌套逻辑有问题,比如:

SED_ARG=" 's/fid=\"${fidMap[$field]}\">.*/fid=\"${fidMap[$field]}\">$newValue<\/$field>/'" $currentFile
eval sed $SED_ARG > tmp && mv tmp $currentFile

这种写法很容易因为变量里的特殊字符(比如newValue含空格、引号)导致sed命令执行失败,进而tmp文件没生成,后续mv同样会报错。我们可以去掉eval,改用sed的原地修改参数-i,既安全又能避免临时文件的mv操作:

把原来的if-else块改成:

grep "<$field" "$currentFile" >/dev/null
if [ $? -eq 0 ]; then
    sed -i.bak "s/fid=\"${fidMap[$field]}\">.*/fid=\"${fidMap[$field]}\">$newValue<\/$field>/" "$currentFile"
    rm "${currentFile}.bak"  # 删除sed自动生成的备份文件
else
    sed -i.bak "s/<\/issue>/<$field fid=\"${fidMap[$field]}\">$newValue<\/$field> <\/issue>/" "$currentFile"
    rm "${currentFile}.bak"
fi

3. 脚本开头的return 0错误

在脚本顶层使用return是不符合shell语法规范的,return是用于函数内返回的,脚本退出应该用exit:

if [ "$1" = "" ] || [ "$2" = "" ] || [ "$3" = "" ]; then
    echo "Please pass in three variables: issueNumber field value"
    echo "Example: new_mod_value.sh 10003 state Approved"
    exit 0  # 将return替换为exit
fi

4. 其他优化建议

  • 给临时文件加上唯一标识(比如tmp.$$),避免和其他脚本的临时文件冲突
  • 添加命令执行结果检查,比如判断accurev xml是否成功,避免后续处理空文件
  • 变量引用尽量加上双引号(比如"$currentFile"),防止文件名含空格时出现异常

修复后的完整脚本

#!/bin/bash
issueNum=$1
field=$2
newValue=$3
typeset -A fidMap
# fidMap['type']=7
#fidMap['customerName']=63
#fidMap['patchNum']=58
#fidMap['releaseImplmntdIn']=42
fidMap['state']=5
#fidMap['subsystem']=13
#fidMap['changeRequestNumber']=36
#fidMap['releaseFoundIn']=39
#fidMap['System']=35
#fidMap['assignedTo']=14

if [ "$1" = "" ] || [ "$2" = "" ] || [ "$3" = "" ]; then
    echo "Please pass in three variables: issueNumber field value"
    echo "Example: new_mod_value.sh 10003 state Approved"
    exit 0
fi

echo "issue number $issueNum"
echo "field is $2"
echo "value is $3"

rm -f runIssue.xml issuesOutputtmp.xml
echo "<queryIssue issueDB=\"TEOCO\" expandUsers=\"true\">" > runIssue.xml
echo "1 == $issueNum" >> runIssue.xml
echo "</queryIssue>" >> runIssue.xml

# 检查accurev查询是否成功
if ! accurev xml -l runIssue.xml > issuesOutputtmp.xml; then
    echo "Error running accurev xml query"
    exit 1
fi

currentFile=issuesOutputtmp.xml

# 使用sed -i原地修改,避免临时文件mv操作
sed -i.bak 's/<issues>/<modifyIssue issueDB="TEOCO">/' "$currentFile" && rm "${currentFile}.bak"
sed -i.bak 's/<\/issues>/<\/modifyIssue>/' "$currentFile" && rm "${currentFile}.bak"
sed -i.bak 's/fid="2">[0-9]*<\/transNum>/fid="2"><\/transNum>/' "$currentFile" && rm "${currentFile}.bak"

grep "<$field" "$currentFile" >/dev/null
if [ $? -eq 0 ]; then
    sed -i.bak "s/fid=\"${fidMap[$field]}\">.*/fid=\"${fidMap[$field]}\">$newValue<\/$field>/" "$currentFile"
    rm "${currentFile}.bak"
else
    sed -i.bak "s/<\/issue>/<$field fid=\"${fidMap[$field]}\">$newValue<\/$field> <\/issue>/" "$currentFile"
    rm "${currentFile}.bak"
fi

# 转义处理
sed -i.bak 's/&/,/g' "$currentFile" && rm "${currentFile}.bak"
#sed -i.bak 's/</\&lt;/g' "$currentFile" && rm "${currentFile}.bak"
#sed -i.bak 's/>/\&gt;/g' "$currentFile" && rm "${currentFile}.bak"
#sed -i.bak 's/"/\&quot;/g' "$currentFile" && rm "${currentFile}.bak"
#sed -i.bak 's/[^!-~\s]//g' "$currentFile" && rm "${currentFile}.bak"

accurev xml -l "$currentFile"

这样修改后,不仅解决了mv: cannot stat 'tmp'的错误,还让脚本更健壮、更易维护。

内容的提问来源于stack exchange,提问作者Stacker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:14:34