如何检查bash中是否存在文件?
当我尝试这样做时:
FILE1="${@:$OPTIND:1}"
if [ ! -e "$FILE1" ]
then
echo "requested file doesn't exist" >&2
exit 1
elif
<more code follows>
我总是得到以下输出:
requested file doesn't exist
程序使用如下:
script.sh [-g] [-p] [-r FUNCTION_ID|-d FUNCTION_ID] FILE
有什么想法吗? 我会很高兴得到任何帮助。
P.S。我希望我可以展示整个文件,而不会因为复制而被解雇。如果有私密的沟通方式,我很乐意帮忙。
我的错误。 Fas强制二进制文件进入错误的位置。感谢大家的帮助。
答案 0 :(得分:3)
调试这样的问题的小技巧。将这些行添加到脚本的顶部:
export PS4="\$LINENO: "
set -xv
set -xv
将在执行前打印出每一行,然后在shell插入变量等时打印出行。$PS4
是set -xv
使用的提示。这将在执行时打印shell脚本的行号。您将能够了解正在发生的事情以及您可能遇到问题的地方。
以下是测试脚本的示例:
#! /bin/bash
export PS4="\$LINENO: "
set -xv
FILE1="${@:$OPTIND:1}" # Line 6
if [ ! -e "$FILE1" ] # Line 7
then
echo "requested file doesn't exist" >&2
exit 1
else
echo "Found File $FILE1" # Line 12
fi
这就是我运行时得到的结果:
$ ./test.sh .profile
FILE1="${@:$OPTIND:1}"
6: FILE1=.profile
if [ ! -e "$FILE1" ]
then
echo "requested file doesn't exist" >&2
exit 1
else
echo "Found File $FILE1"
fi
7: [ ! -e .profile ]
12: echo 'Found File .profile'
Found File .profile
在这里,我可以看到我将$FILE1
设置为.profile
,并且我的脚本理解${@:$OPTIND:1}
。关于这一点的最好的事情是它适用于所有shell到原始的Bourne shell。这意味着如果您没有按照自己的想法运行Bash,那么您将看到脚本失败的位置,并可能解决问题。
我怀疑你可能没有在Bash中运行你的脚本。你把#! /bin/bash
放在了最前面吗?
script.sh [-g] [-p] [-r FUNCTION_ID | -d FUNCTION_ID] FILE
您可能希望使用getopts
来解析参数:
#! /bin/bash
USAGE=" Usage:
script.sh [-g] [-p] [-r FUNCTION_ID|-d FUNCTION_ID] FILE
"
while getopts gpr:d: option
do
case $option in
g) g_opt=1;;
p) p_opt=1;;
r) rfunction_id="$OPTARG";;
d) dfunction_id="$OPTARG";;
[?])
echo "Invalid Usage" 1>&2
echo "$USAGE" 1>&2
exit 2
;;
esac
done
if [[ -n $rfunction_id && -n $dfunction_id ]]
then
echo "Invalid Usage: You can't specify both -r and -d" 1>&2
echo "$USAGE" >2&
exit 2
fi
shift $(($OPTIND - 1))
[[ -n $g_opt ]] && echo "-g was set"
[[ -n $p_opt ]] && echo "-p was set"
[[ -n $rfunction_id ]] && echo "-r was set to $rfunction_id"
[[ -n $dfunction_id ]] && echo "-d was set to $dfunction_id"
[[ -n $1 ]] && echo "File is $1"
答案 1 :(得分:1)
To(回顾)并添加到@ DavidW。的优秀答案:
检查脚本的shebang行(第一行)以确保它由bash
执行:是#!/bin/bash
还是#!/usr/bin/env bash
?
检查脚本文件中是否存在可能导致意外行为的隐藏控制字符(例如\r
);运行cat -v scriptFile | fgrep ^
- 它应该产生NO输出;如果该文件包含\r
个字符,则会显示为^M
。
\r
个实例(更准确地说,要将Windows风格的\r\n
换行序列转换为Unix \n
- 仅限序列),您可以使用dos2unix file
进行转换到位;如果您没有此实用程序,可以使用sed 's/'$'\r''$//' file > outfile
(CAVEAT:使用不同的输出文件,否则您将销毁您的输入文件);要删除所有 \r
个实例(即使后面没有\n
),请使用tr -d '\r' < file > outfile
(CAVEAT:使用不同的输出文件,否则你会破坏你的输入文件)。i=0; for a; do echo "\$$((i+=1))=[$a]"; done
(将值括在[...]
(例如)中的目的是查看值的确切边界。)
这会产生类似的结果:
$1=[-g]
$2=[input.txt]
...
但请注意,如果没有传递任何参数,则不会打印任何内容。
答案 2 :(得分:0)
尝试打印FILE1以查看它是否具有您想要的值,如果不是问题,这是一个简单的脚本(下面的站点):
#!/bin/bash
file="${@:$OPTIND:1}"
if [ -f "$file" ]
then
echo "$file found."
else
echo "$file not found."
fi
http://www.cyberciti.biz/faq/unix-linux-test-existence-of-file-in-bash/
答案 3 :(得分:0)
不是以一种棘手的方式从“$ @”中拔出一个项目,为什么不用shift
关闭你用getopts处理过的args:
while getopts ...
done
shift $(( OPTIND - 1 ))
FILE1=$1