Make a Bash script exit and print error message if users call the script incorrectly

Script was needed

#!/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" 

Change, the script has changed to

 grep -P "^[\s]*[0-9A-Za-z-]+.?[\s]*$" $* if [ ! -f "$1" ]; then echo 'Usage: ' echo echo './Scriptname inputfile > outputfile' exit 0 fi 

calling a script without parameters does not give erros and sits empty

 Usage: ./Scriptname inputfile > outputfile 

I have a bit of code

 grep -P "^[\s]*[0-9A-Za-z-]+.?[\s]*$" $* 

This code pulls out lines containing one word and outputs to a new file, for example

 This is a multi word line this the above line is not now once again wrong 

The output will be

 This now 

Code works, users call code with ./scriptname file > newfile

However, I am trying to deploy the code to give users an error message if they incorrectly reference the script.

For the messange error, I am thinking of repeating something like scriptname file_to_process > output_file .

I tried

 if [incorrectly invoted unsure what to type] echo $usage exit 1 Usage="usage [inputfile] [>] [outputfile] 

However, I’m out of luck. The code works, but does nothing if I only call the script name. Also, if I call the script only with the script name and input file, it will output the results instead of exiting with an error message.

The others I tried

 if [ ! -n $1 ]; then echo 'Usage: ' echo echo './Scriptname inputfile > outputfile' exit 0 fi 

Given the answers I have received so far, my code is now

 #!/bin/bash grep -P "^[\s]*[0-9A-Za-z-]+.?[\s]*$" $* if [ ! -f "$1" ]; then echo 'Usage: ' echo echo './Scriptname inputfile > outputfile' exit 0 fi 

When calling a script without an input file, the script does nothing and should be interrupted by ctrl + c, while still trying to get an echo of the invoke message.

+4
source share
4 answers

When you call the script as ./scriptname file > newfile , the shell interprets file as the only argument ./scriptname . This is because > is the standard output redirection operator.

I would suggest two possible alternatives:


Alternative 1 : Maybe you can try passing this as one argument?
 ./scriptname 'file > newfile' 

In this case, one way to check the format would be

 #!/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]}" 

Note If you are checking to see if the arguments are valid or not, it is usually best to run commands only after the validation is complete.


Alternative 2 : Passing 2 arguments, such as

 ./scriptname file newfile 

the script is as follows

 #!/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" 
+2
source

I would use a parameter extension for this:

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

If the script is called without arguments (that is, $1 not canceled), the extension ${var:?error message} Error ${var:?error message} causes the shell to display an error with this message and exit. Otherwise, the first argument is assigned to $inputfile .

+3
source

Try adding double quotes around $1 and using -f to check for availability and is a normal file:

 if [ ! -f "$1" ]; then echo 'Usage: ' echo echo './Scriptname inputfile > outputfile' exit 0 fi 
+1
source

You can also check the number of parameters with $# and cat usage message:

 if [ ! $# -eq 1 ]; then cat << EOF Usage: $0 'input_file' > output_file EOF exit 1 fi 
+1
source

Source: https://habr.com/ru/post/1440683/


All Articles