2

I'm stuck again. In this case, I'm trying to get a homework from last week to do text transformations when the name of the file is put on the command line. The script from last week cut out columns and rearranged them and replaced certain characters as well as deleted some spaces. For this week, the homework is asking to modify the script to include if/then arguments.

This is what I have so far:

if [ $# -gt 0 ] 
then
    ./hw9.sh
else
     echo "Please enter a filename"
fi
name=First \Last
echo $name
starting_info=raw_info
date
#Pretend the rest of my original script is here#

So, when I test it and type ./hw9.sh raw_info it works, but also still echoes Please enter a filename and runs my original ./hw9.sh script twice. It's supposed to echo Please enter a filename if the user just types ./hw9.sh on the command line and it's supposed to run my original script if the user types ./hw9.sh raw_info

Can someone provide some guidance? Thank you!

3
  • What is in hw9.sh?
    – terdon
    Commented Oct 23, 2022 at 12:50
  • It's a script that cut and pasted columns with data in a different order (columns were: id, last, first and it's supposed to read first, last then id without "-" in the ids
    – Rene Rojo
    Commented Oct 23, 2022 at 15:13
  • 1
    name=First \Last -- this would likely give an error like "Last: command not found". Maybe you mean name=First\ Last, or perhaps better: name="First Last"
    – ilkkachu
    Commented Oct 23, 2022 at 19:17

2 Answers 2

5

Based on your description, I believe you have one script that's named hw9.sh, and that you have set up a recursive execution condition.

When you run hw9.sh raw_info, the if condition is true ($# = 1), and the script hw9.sh is executed. In this nested execution, the if condition is false ($# = 0), so the script echoes the prompt and continues execution from there. After the nested execution is complete, the control returns to the parent script and then it executes the rest of the script after the if body. So, the script effectively runs twice.

Instead of using recursion, you could use a condition like this to catch the situation where you don't have a positional argument.

if [[ $# -eq 0 ]];
then echo 'A filename is required.'
exit 1
fi

This doesn't take into account situations where you have more than one positional parameter, or one where the parameter is not the string 'raw_info'. You can consider adding those as well.

Also, to align your final script with best practices, take a look at https://www.shellcheck.net/ .

2

There's no point in asking for a file name if you don't actually take it and do something. So let's make your script operate on a file if one is given and is a valid, regular file, and on a default file name if no file is given. Let's also add some basic error checking:

#!/bin/bash

## Set the default input file
file_name="raw_info"

# Exit if we have more than one argument
if [ $# -gt 1 ]; then
    echo "This script can only take one argument." >&2
    exit 1
# If we have exactly one argument, check that it is an existing file
elif [ $# -eq 1 ]; then
    if [ -f "$1" ]; then
      file_name="$1"
      echo "I will work on provided file '$file_name'."
    elif [ -d "$1" ]; then
        echo "You gave '$1', but that is a directory!"
        exit 2  
    else
        echo "You gave '$1' but it isn't an existing regular file!" >&2
        exit 3 
    fi
else
    if [ -e "$file_name" ]; then
        echo "No file name given, I will work on '$file_name'." >&2
    else
        echo "No file name given and default file name '$file_name' not found!" >&2
        exit 4
    fi
fi

### Assuming you want the script from https://unix.stackexchange.com/q/721051
cut -f3 -d, "$file_name" > first
cut -f2 -d, "$file_name" > last
cut -f1 -d, "$file_name" > id

This script will run the cut commands on whatever file is stored in the $file_name variable and that will be the default raw_info if no arguments are given to the script, or whatever argument you give if you pass an argument. The >&2 just sends error and info messages to standard error. For help on the various tests used, run help test in your terminal.

2
  • What is the exit command when using in script? We haven't learned about that yet
    – Rene Rojo
    Commented Oct 23, 2022 at 15:16
  • 1
    @ReneRojo it allows you to stop the script and return a specific exit value. See help exit in a bash shell.
    – terdon
    Commented Oct 23, 2022 at 19:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .