如果用户错误地调用脚本,请退出Bash脚本并打印错误消息

如果用户错误地调用脚本,请退出Bash脚本并打印错误消息,bash,error-handling,multiplicity,Bash,Error Handling,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]

需要的脚本是

#!/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"
编辑,脚本已更改为

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

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

fi
在没有参数的情况下调用脚本不会产生任何错误,并且是空白的

Usage: 

./Scriptname inputfile > outputfile
我有一些代码

grep -P "^[\s]*[0-9A-Za-z-]+.?[\s]*$" $*
这段代码提取上面只有一个单词的行,并将输出输出到一个新文件,例如

输出将是

This
now
代码可以工作,用户使用
/scriptname file>newfile

但是,如果用户错误地调用脚本,我将尝试扩展代码以向用户提供错误消息

对于错误消息,我考虑将类似
scriptname file\u的内容回显到\u process>output\u file

我确实试过了

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

exit 1
Usage="usage [inputfile] [>] [outputfile]
然而,我运气不好。如果仅使用脚本名调用,代码将运行,但不会执行任何操作。另外,如果我只使用scriptname和输入文件调用脚本,它将输出结果,而不是带着错误消息退出

其他我试过的是

if [ ! -n $1 ]; then

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

fi
考虑到目前为止我收到的回复,我现在的代码是

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

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

fi

当在没有输入文件的情况下调用脚本时,脚本什么也不做,必须使用ctrl+c中止,仍然试图获取调用消息的回音

尝试在
$1
周围添加双引号,并使用
-f
检查文件是否存在且是否正常:

if [ ! -f "$1" ]; then

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

fi

您还可以使用
$#
cat
使用信息检查参数计数:

if [ ! $# -eq 1 ]; then
cat << EOF
    Usage:

    $0 'input_file' > output_file
EOF
    exit 1
fi
if[!$#-eq 1];然后
cat输出文件
EOF
出口1
fi

当您像
/scriptname file>newfile
那样调用脚本时,shell将
文件
解释为
/scriptname
的唯一参数。这是因为
是标准的输出重定向操作符

我想提出两个可能的备选方案:


备选方案1: 也许你可以试着像这样把它作为一个论点来传递

./scriptname 'file > newfile'
在这种情况下,检查格式的一种方法是

#!/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]}"
注意:如果要检查参数是否有效,通常最好只在检查完成后运行命令


备选方案2: 传递2个参数,如

./scriptname file newfile
脚本如下所示

#!/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"
我会用这个:

inputfile=${1:?Usage: $(basename $0) inputfile > outputfile}

如果在没有参数的情况下调用脚本(即,
$1
未设置),
${var:?error message}
扩展会导致shell显示带有给定消息的错误并退出。否则,第一个参数将分配给
$inputfile

您是否使用
/bin/bash
/bin/sh
?在命令行上使用
“$@”
而不是
$*
;它将文件名参数中的空格保留为空格。如果将
grep-P-e“…您的正则表达式…”
与表达式前面的
-e
一起使用,则用户可以在命令行上键入类似
-n
-l
的选项,并且
grep
将适当修改其行为。(在使用GNU
getopt()
来排列参数的系统上,您可能不需要指定
-e
;我不喜欢该功能。)好的,我将更改$@now而不是
[!-n$1]
使用
[-z“$1]”
。另外,将grep放在参数计数测试之后,而不是之前。如果它在前面,并且没有参数,它将坐在那里等待您在stdin上输入。要进行实验,请尝试在命令行中使用
grep x
而不使用文件名,并键入一些包含和不包含x的行,然后^D退出。好的,我厌倦了使用
grep-P“^[\s]*[0-9A-Za-z-]+。?[\s]*$”$*如果[!-f“$1]”;然后echo‘用法:echo echo’。/Scriptname inputfile>outputfile’退出0 fi
当我调用它时,它只是坐在那里,什么也没做,我试着只用脚本名调用,我在使用代码时是否遗漏了一些东西。而不是使用
[!$#-eq 1]
使用
[$#-ne 1]
谢谢,唯一的问题是输出是
用法:$0[inputfile][>][outputfile]
,因此我只需要在最后一个fi之后添加另一个,退出0是否正确?脚本将运行
grep
,如果
grep
成功运行,脚本将以状态0退出,因此您实际上不需要脚本中的
退出0
(如果我理解你所说的…)好问题-对于简单脚本来说,这是一个优雅的单行解决方案,对我来说效果很好,谢谢!另外,如果需要更清楚地格式化用法,您似乎可以将错误消息拆分为脚本中的行,并且输出将反映相同的换行符
inputfile=${1:?Usage: $(basename $0) inputfile > outputfile}