Завершите работу скрипта Bash и напечатайте сообщение об ошибке, если пользователи некорректно вызывают скрипт

Скрипт нужен был

#!/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 is a multi word line
this
the above line is not
now
once again wrong

Выход будет

This
now

Код работает, пользователи вызывают код, используя ./scriptname file > newfile

Тем не менее, я пытаюсь расширить код, чтобы дать пользователям сообщение об ошибке, если они неправильно запускают скрипт.

Из-за сообщения об ошибке я думаю повторить что-то вроде scriptname file_to_process > output_file,

Я попробовал

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

exit 1
Usage="usage [inputfile] [>] [outputfile]

Однако мне мало повезло. Код запускается, но ничего не делает, если я вызываю только с именем скрипта. Кроме того, если я вызову сценарий только с именем сценария и входным файлом, он выведет результаты вместо выхода с сообщением об ошибке.

Другие, которые я пробовал

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, все еще пытаясь получить эхо сообщения invoke.

4 ответа

Решение

Когда вы вызываете скрипт как ./scriptname file > newfile оболочка интерпретирует file в качестве единственного аргумента ./scriptname, Это потому что > является стандартным оператором перенаправления вывода.

Я хотел бы предложить 2 возможных варианта:


Альтернатива 1: Может быть, вы можете попробовать передать это как 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} расширение заставляет оболочку отображать ошибку с данным сообщением и завершаться. В противном случае первый аргумент присваивается $inputfile,

Попробуйте добавить двойные кавычки вокруг $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
Другие вопросы по тегам