2

I wrote a script in bash to basically create aliases, but for any reason, it doesn't work in some cases. Here it's the code:

#!/bin/bash
#Script to create unique and permanent aliases

_add_alias()
{
    echo "alias $1='$2'" | sudo tee -a $HOME/.bash_aliases
    echo "Alias successfully created"
}

if [ `cat $HOME/.bash_aliases | grep "alias $1=" | wc -l` == 0 ]
    then
    if [ $# -eq 2 ]
        then
        if [ -f "$2" ] #This condition is always false, don't know why.
            then
            _add_alias $1 "$2"
        elif $2 > tmp.txt 2> tmp.txt
            then
            _add_alias $1 "$2"
        else
            echo "Wrong command"
        fi
        rm tmp.txt
    elif [ $# -gt 2 ]
        then
    echo "Error: Usage: addal alias_name 'command' (comand between quotes)"
    elif [ $# -lt 2 ]
        then
        echo "Wrong number of parameters"
    fi
else
    echo "Alias name already exists"
fi

I hope you could help me fix the script.

13
  • What cases does it work and when does it fail?
    – Oli
    Apr 14, 2015 at 11:21
  • It doesn't work when $2 is the path to a script, for example, "$HOME/.bash_script/alias_creator.sh" Apr 14, 2015 at 11:23
  • 4
    Well.. 1. [ -f $2 ] - do you expect $2 to be a path to some file? 2. sudo tee -a? You don't need sudo to write to your own home folder unless your permissions are messed up. 3. You could replace that big if condition with: if ! grep -q "alias $1=" $HOME/.bash_aliases"; then.
    – muru
    Apr 14, 2015 at 11:24
  • 1
    @FranciscoGallegoSalido what happens in that case? An alias doesn't get created, or an incorrect one gets created?
    – muru
    Apr 14, 2015 at 11:25
  • 1
    Please translate the Spanish bits. It will make your question much more likely to get a reasonable answer (since it aids understanding of what the problem is), and will make the question and answer more usable for future users.
    – l0b0
    Apr 14, 2015 at 13:14

3 Answers 3

2

Here are your errors (source):

  • SC2002 Useless cat. Consider 'cmd < file | ..' or 'cmd file | ..' instead.
  • SC2006 Use $(..) instead of legacy `..`.
  • SC2046 Quote this to prevent word splitting.
  • SC2086 Double quote to prevent globbing and word splitting.
  • SC2126 Consider using grep -c instead of grep|wc.

   1  #!/bin/bash
   2  #Script to create unique and permanent aliases
   3  
   4  _add_alias()
   5  {
   6      echo "alias $1='$2'" | sudo tee -a $HOME/.bash_aliases
                                             ^––SC2086 Double quote to prevent globbing and word splitting.
   7      echo "Alias successfully created"
   8  }
   9  
  10  if [ `cat $HOME/.bash_aliases | grep "alias $1=" | wc -l` == 0 ]
           ^––SC2046 Quote this to prevent word splitting.
           ^––SC2006 Use $(..) instead of legacy `..`.
                ^––SC2086 Double quote to prevent globbing and word splitting.
                ^––SC2002 Useless cat. Consider 'cmd < file | ..' or 'cmd file | ..' instead.
                                      ^––SC2126 Consider using grep -c instead of grep|wc.
  11      then
  12      if [ $# -eq 2 ]
  13          then
  14          if [ -f "$2" ] #This condition is always false, don't know why.
  15              then
  16              _add_alias $1 "$2"
                             ^––SC2086 Double quote to prevent globbing and word splitting.
  17          elif $2 > tmp.txt 2> tmp.txt
  18              then
  19              _add_alias $1 "$2"
                             ^––SC2086 Double quote to prevent globbing and word splitting.
  20          else
  21              echo "Wrong command"
  22          fi
  23          rm tmp.txt
  24      elif [ $# -gt 2 ]
  25          then
  26      echo "Error: Usage: addal alias_name 'command' (comand between quotes)"
  27      elif [ $# -lt 2 ]
  28          then
  29          echo "Wrong number of parameters"
  30      fi
  31  else
  32      echo "Alias name already exists"
  33  fi
0
2

Here you're a corrected and improved script:

#!/bin/bash

###################################################
## Script to create permanent and unique aliases ##
###################################################

## alias is equal to the first argument.
alias="$1"

## command is equal to an array holding all
## the positional parameters minus the first.
## (i.e. for "ls -la" it would be ["ls, "-la"]).
command=("${@:2}")

## If .bash_aliases exists, load it. Now the alias check
## will take in account any alias not sourced yet on the current shell.
test -f ~/.bash_aliases && source $_

## If there are less than 2 parameters, prints the usage and exits.
if [ $# -lt 2 ]; then
    echo "Usage: $0 <alias_name> <command>"
    exit 1
fi

## If the command is not valid, prints an error and exits.
if ! type "${command[0]}" &> /dev/null; then
    echo "Wrong command"
    exit 3
fi

## If the current alias already exists, prints a error message and then exits.
if [[ "$(type -t '$alias')" == "alias" ]]; then
    echo "This alias alredy exists"
    exit 2
fi

## Append the alias to the .bash_aliases file.
echo "alias $alias='${command[@]}'" >> ~/.bash_aliases

## Print a sucess message.
echo "Alias '$alias' linked to the command '${command[@]}'!" 

Things that I changed:

  • Commented code.
  • Used type to detemine if the alias already exists.
  • Removed the function because I think that is not necessary.
  • Used type to detemine if a command is valid or not.
  • Removed some unnecessary elif.
  • Improved the conditionals.
  • command may be unquoted (i.e. myscript pingoogle ping google.com)
6
  • I tried it and still doesn't work. Note that "$HOME/.bash_aliases" needs sudo permissions, that's why I used sudo tee -a Apr 14, 2015 at 11:44
  • Why needs sudo permissions?
    – 0x2b3bfa0
    Apr 14, 2015 at 11:52
  • Don't really know why, but it works that way and that's all Apr 14, 2015 at 11:54
  • doesn't works with "ls -la" as alias
    – A.B.
    Apr 14, 2015 at 12:07
  • 1
    @FranciscoGallegoSalido -Almost- Everything in your home directory should be yours, and shouldn't require sudo. Make sure you are the owner of the ~/.bash_aliases file. If you ran sudo on it before, then most likely root took ownership. Take ownership back with sudo chmod $USER: ~/.bash_aliases
    – Dan
    Apr 21, 2015 at 8:38
0

Some thoughts:

myscript alias1 "$HOME/dir/ascript"

will evaluate in test part to

[ -f '/home/me/dir/ascript' ]

which may be true or false.

myscript alias2 '$HOME/dir/anotherscript'

will evaluate in test part to

[ -f '$HOME/dir/ascript' ]

which is always false (unless you have a dir named $HOME in local dir).

and

myscript alias3 "$HOME/dir/sample.sh foo bar"

will evaluate in test part to

[ -f '/home/me/dir/sample.sh foo bar' ]

which is false, unless there is a 'sample.sh foo bar' file in /home/me/dir.

and you should fix .bash_aliases and use

echo "alias $1='$2'" >> $HOME/.bash_aliases
1
  • Yes!! Finally!! That was the error, I should have used doble quotes instead of singles ones, that's why it always evaluates falses ^^' Thank you very much! Apr 14, 2015 at 14:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.