Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SED in bash for receiving parameters

Tags:

bash

sed

This is my script, in which I want to receive arguments --path and --mode by user, for example:

./myscript.sh --path=/hello --mode=a

script

#!/usr/bin/env bash

set -e

HELP=false
MODE=false
PATH=false

for arg in "$@"
do
    case "$arg" in
        -h|--help) 
            HELP=true
            ;;      
        --mode*)
            MODE=`echo $arg | sed -e 's/^[^=]*=//g'`
            ;;
        --path*)
            PATH=`echo $arg | sed -e 's/^[^=]*=//g'`
            ;;      
        *)
            echo "wrong argument: $arg"
            echo "type --help for supported parameters"
            exit 1
        ;;

    esac
done

When I try to execute, I receive this error:

line 19: sed: command not found

What's wrong ?

like image 950
Fabrizio Stellato Avatar asked Dec 13 '25 07:12

Fabrizio Stellato


2 Answers

PATH=false

This line destroys your PATH variable. PATH is where the shell looks up all commands you want to run. (External commands, that is; built-in shell commands, functions, and aliases are not affected.)

Normally it contains things like PATH=/usr/local/bin:/usr/bin:/bin. By setting it to false you're telling bash to search the (non-existent) directory false for commands.

This is why sed (which is an external command) cannot be found.

In general you should avoid ALL_UPPERCASE names for your own script variables because many of those ALL_UPPERCASE variables are reserved / already used by the shell or the system in general.


You said you're running this on Windows. I believe environment variables are case-insensitive on Windows, so even using path instead may not help here. You may have to choose a different name for your variable, such as my_path.

like image 174
melpomene Avatar answered Dec 15 '25 16:12

melpomene


The nice answer @melpomene gave fixes your immediate sed problem, and it also mentions one good habit in shell programming -- avoiding uppercase names for non-environment variables (you might find Google's Shell Style Guide, variable names section helpful).

But besides that, your sed line is completely unnecessary. You can replace the expensive command substitution and call to the external sed:

MODE=`echo $arg | sed -e 's/^[^=]*=//g'

with shell parameter expansion, prefix pattern strip:

mode="${arg#*=}"

Also, when using command substitution, better use the $(command) form instead of backticks (also mentioned in the style guide cited above). It'll be easier to read, and to nest other calls to command substitutions (all characters between the parentheses make up the command; none are treated specially).

When iterating over arguments, you might find the while (($# > 0)) loop more convenient (coupled with shift N), if you need to handle parameters with varying number of arguments, e.g. -m val, -mval and --mode=val. But in that case you would be better off with getopts (few examples here) anyway.

like image 36
randomir Avatar answered Dec 15 '25 15:12

randomir



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!