Bash 为什么我的脚本在执行命令后突然退出?
我正试图按照以下说明为Dash生成文档集:。 问题是,该脚本在wget之后不会继续,并且似乎不会抛出任何错误。当我将脚本复制到终端时,一切都正常 我使用的是MacOS 10.8.4和默认的bashBash 为什么我的脚本在执行命令后突然退出?,bash,shell,wget,exitstatus,Bash,Shell,Wget,Exitstatus,我正试图按照以下说明为Dash生成文档集:。 问题是,该脚本在wget之后不会继续,并且似乎不会抛出任何错误。当我将脚本复制到终端时,一切都正常 我使用的是MacOS 10.8.4和默认的bash #!/usr/bin/env bash set -e mkdir -p $1.docset/Contents/Resources/Documents/ echo "THIS RUNS" wget -rkp -l3 -np -nH --cut-dirs=1 --directory
#!/usr/bin/env bash
set -e
mkdir -p $1.docset/Contents/Resources/Documents/
echo "THIS RUNS"
wget -rkp -l3 -np -nH --cut-dirs=1 --directory-prefix="./"$1".docset/Contents/Resources/Documents/" $2
echo "THIS DOES NOT RUN"
sed "s/NAME/$1/g" template > $1.docset/Contents/Info.plist
touch $1.docset/Contents/Resources/docSet.dsidx
# (script continues)
我看了其他帖子,比如,但我没有在这里使用exec
脚本为什么退出?更新 我最初的回答是对你的问题的误解。一个似乎是问题的问题是您的:
INSERT INTO searchIndex (name, type, path) VALUES (index, Guide, 'index.html');
我不确定。但似乎您可能希望创建索引
和指南
字符串,如下所示:
INSERT INTO searchIndex (name, type, path) VALUES ('index', 'Guide', 'index.html');
您启用了
set-e
akaerrexit
如果其中一个命令返回非零退出代码,脚本将退出,并且可能并不总是很明显哪个命令失败:
- 有些人可能会打印一个有用的错误来识别自己和问题
- 一些(如
)可能会在返回的一页页输出中简要地提到一个错误wget
- 有些(如
)可能根本不显示错误或任何输出,脚本只是退出grep
-x
akaxtrace
运行脚本:
bash -x script.sh
或者将set-x
添加到脚本本身:
set -x
set -e
...
这将导致脚本打印出正在执行的每个命令,以便您可以看到最后一个命令
如果要忽略命令的退出状态,可以添加| | true
:
# Causes exit if you lack read permission on any directory
find . -name '*.sh'
# Does not cause the script to exit
find . -name '*.sh' || true
如果希望在脚本中触发set-e
时收到警报,可以设置陷阱:
#!/bin/bash
set -e
# Show error if commands exit with non-zero
trap 'ret=$?; echo "$0:$LINENO: Error: set -e triggered"; exit $ret' ERR
# Would have failed silently
grep doesnotexist /etc/passwd
echo "This does not run"
执行时:
$ ./foo
./foo:6: Error: set -e triggered
尝试使用here文档,如下所示:
cat > "$1.docset/Contents/Info.plist" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleIdentifier</key>
<string>$1</string>
<key>CFBundleName</key>
<string>$1</string>
<key>DocSetPlatformFamily</key>
<string>$1</string>
<key>isDashDocset</key>
<true/>
</dict>
</plist>
EOF
cat>“$1.docset/Contents/Info.plist”wget的退出状态8意味着其中一个文件服务器返回了错误(例如404):
服务器发出了错误响应
您可能希望修复URL,使其指向正确的URL,或者忽略wget
的退出状态,例如
wget ... || true
注意:除非启用了pipefail
选项,否则上述操作将有效
另一种方法是比较退出状态,并在返回时忽略8,例如:
wget ... || { [ $? -ne 0 ] && [ $? -ne 8 ] && echo Success || exit 1; }
请参阅:按照预期,$1(文档集的名称)被连接到前缀中。是否有更好的(正确的、不中断的)方法来执行此操作?是否可以共享用于命令行参数的值?尝试一下,就像在wget完成之前它工作正常一样,然后忽略所有其他内容。@basszwo您没有看到其他人运行吗?这是wget的问题。您是否可以向其添加-v
或-verbose
选项以查看可能的错误消息。Wget收到了大量404错误,并返回退出状态8(echo$?)。实际问题解决了,但是,我仍然不知道该怎么办:删除“set-e”很好,但感觉不对。@basszwo您还应该引用变量,以防止分词,这会导致您的参数和文件创建不同。e、 g.“--directory prefix=./$1.docset/Contents/Resources/Documents/”“$2”
我怀疑set-e
导致$1变为-e
。如果我错了,请纠正我。没错,谢谢。但这并不能解决问题。wget行之后的任何内容都将被完全忽略。