如何检查 bash 中文件是否存在?
当我尝试这样做时:
FILE1="${@:$OPTIND:1}"
if [ ! -e "$FILE1" ]
then
echo "requested file doesn't exist" >&2
exit 1
elif
<more code follows>
Run Code Online (Sandbox Code Playgroud)
我总是得到以下输出:
requested file doesn't exist
Run Code Online (Sandbox Code Playgroud)
该程序的使用方式如下:
script.sh [-g] [-p] [-r FUNCTION_ID|-d FUNCTION_ID] FILE
Run Code Online (Sandbox Code Playgroud)
有什么想法吗?我将很高兴提供任何帮助。
PS 我希望我可以展示整个文件,而不用担心因为有副本而被学校开除。如果有私人的沟通方式,我会很乐意帮忙。
我的错。Fas 将二进制文件强制放入错误的位置。感谢大家的帮助。
调试此类问题的小技巧。将这些行添加到脚本的顶部:
export PS4="\$LINENO: "
set -xv
Run Code Online (Sandbox Code Playgroud)
会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
Run Code Online (Sandbox Code Playgroud)
这是我运行它时得到的结果:
$ ./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
Run Code Online (Sandbox Code Playgroud)
在这里,我可以看到我设置$FILE1为.profile,并且我的脚本理解该${@:$OPTIND:1}。最好的事情是它适用于所有 shell,直到原始的 Bourne shell。这意味着,如果您没有像您想象的那样运行 Bash,您将看到脚本失败的地方,并可能解决问题。
我怀疑您可能没有在 Bash 中运行脚本。你贴#! /bin/bash在上面了吗?
script.sh [-g] [-p] [-r FUNCTION_ID|-d FUNCTION_ID] 文件
您可能想使用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"
Run Code Online (Sandbox Code Playgroud)
(回顾)并添加到@DavidW. 的优秀答案:
检查脚本的shebang 行bash(第一行)以确保它是通过以下方式执行的:是#!/bin/bash还是#!/usr/bin/env bash?
检查脚本文件中是否存在可能导致意外行为的隐藏控制字符(例如);\rrun cat -v scriptFile | fgrep ^- 它应该产生 NO 输出;如果文件确实包含\r字符,它们将显示为^M.
\r实例(更准确地说,是将 Windows 样式的\r\n换行序列转换为 Unix\n专用序列),您可以使用就地dos2unix file转换;如果你没有这个实用程序,你可以使用(警告:使用不同的输出文件,否则你会破坏你的输入文件);要删除所有实例(即使后面没有),请使用 (警告:使用不同的输出文件,否则您将破坏输入文件)。sed 's/'$'\r''$//' file > outfile \r\ntr -d '\r' < file > outfilei=0; for a; do echo "\$$((i+=1))=[$a]"; done
Run Code Online (Sandbox Code Playgroud)
(将值括在[...](例如) 中的目的是查看值的确切边界。)
这将产生类似的结果:
$1=[-g]
$2=[input.txt]
...
Run Code Online (Sandbox Code Playgroud)
但请注意,如果没有传递任何参数,则不会打印任何内容。