如果用户不正确地调用脚本,则使Bash脚本退出并打印错误消息

Aus*_*dog 5 error-handling bash multiplicity

所需的脚本是

#!/bin/bash

# Check if there are two arguments
if [ $# -eq 2 ]; then
   # Check if the input file actually exists.
   if ! [[ -f "$1" ]]; then
     echo "The input file $1 does not exist."
     exit 1
   fi
else
   echo "Usage: $0 [inputfile] [outputfile]"
   exit 1
fi

# Run the command on the input file
grep -P "^[\s]*[0-9A-Za-z-]+.?[\s]*$" "$1" > "$2"
Run Code Online (Sandbox Code Playgroud)

编辑,脚本已更改为

grep -P "^[\s]*[0-9A-Za-z-]+.?[\s]*$" $*
if [ ! -f "$1" ]; then

  echo 'Usage: '
  echo
  echo './Scriptname inputfile > outputfile'
  exit 0

fi
Run Code Online (Sandbox Code Playgroud)

不带参数调用脚本不会产生错误,并且会留空

Usage: 

./Scriptname inputfile > outputfile
Run Code Online (Sandbox Code Playgroud)

我有一点代码

grep -P "^[\s]*[0-9A-Za-z-]+.?[\s]*$" $*
Run Code Online (Sandbox Code Playgroud)

这段代码拉上只有一个单词的行,然后将输出泵送到新文件中,例如

This is a multi word line
this
the above line is not
now
once again wrong
Run Code Online (Sandbox Code Playgroud)

输出将是

This
now
Run Code Online (Sandbox Code Playgroud)

该代码有效,用户使用 ./scriptname file > newfile

但是,我正在尝试扩展代码,以便在用户错误地调用脚本时为他们提供一条错误消息。

对于错误信息,我正在考虑回显类似的东西scriptname file_to_process > output_file

我确实尝试过

if [incorrectly invoted unsure what to type]
echo $usage

exit 1
Usage="usage [inputfile] [>] [outputfile]
Run Code Online (Sandbox Code Playgroud)

但是我运气不好。该代码可以运行,但是如果仅使用脚本名称进行调用,则不会执行任何操作。另外,如果仅使用脚本名称和输入文件来调用脚本,它将输出结果,而不是退出并显示错误消息。

我尝试过的其他

if [ ! -n $1 ]; then

  echo 'Usage: '
  echo 
  echo './Scriptname inputfile > outputfile'
  exit 0

fi
Run Code Online (Sandbox Code Playgroud)

鉴于我到目前为止收到的答复,我的代码现在是

#!/bin/bash
grep -P "^[\s]*[0-9A-Za-z-]+.?[\s]*$" $*
if [ ! -f "$1" ]; then

  echo 'Usage: '
  echo 
  echo './Scriptname inputfile > outputfile'
  exit 0

fi
Run Code Online (Sandbox Code Playgroud)

当在没有输入文件的情况下调用脚本时,该脚本不执行任何操作,必须使用ctrl + c中止该脚本,但仍尝试获取调用消息的回显。

dou*_*own 3

当您调用类似 的脚本时./scriptname file > newfile,shell 会将其解释file为 的唯一参数./scriptname。这是因为>是标准输出重定向运算符。

我想提出两种可能的替代方案:


替代方案 1:也许您可以尝试将其作为 1 个参数传递,如下所示?

./scriptname 'file > newfile'
Run Code Online (Sandbox Code Playgroud)

在这种情况下,检查格式的一种方法是

#!/bin/bash

# Check if the format is correct
if [[ $1 =~ (.+)' > '(.+) ]]; then
  # Check if the input file actually exists.
  if ! [[ -f "${BASH_REMATCH[1]}" ]]; then
    echo "The input file ${BASH_REMATCH[1]} does not exist!"
    exit 1
  fi
else
  echo "Usage: $0 \"[inputfile] [>] [outputfile]\""
  exit 1
fi

# Redirect standard output to the output file
exec > "${BASH_REMATCH[2]}"
# Run the command on the input file
grep -P "^[\s]*[0-9A-Za-z-]+.?[\s]*$" "${BASH_REMATCH[1]}"
Run Code Online (Sandbox Code Playgroud)

注意:如果您要检查参数是否有效,通常最好仅在检查完成后运行命令。


替代方案 2:传递 2 个参数,例如

./scriptname file newfile
Run Code Online (Sandbox Code Playgroud)

脚本看起来像这样

#!/bin/bash

# Check if there are two arguments
if [ $# -eq 2 ]; then
   # Check if the input file actually exists.
   if ! [[ -f "$1" ]]; then
     echo "The input file $1 does not exist."
     exit 1
   fi
else
   echo "Usage: $0 [inputfile] [outputfile]"
   exit 1
fi

# Run the command on the input file
grep -P "^[\s]*[0-9A-Za-z-]+.?[\s]*$" "$1" > "$2"
Run Code Online (Sandbox Code Playgroud)