0

I wrote a simple script to go through my development project directory and add an alias shortcut for each one:

shopt -s dotglob #Use shopt -u dotglob to exclude hidden directories
find ~/development/* -prune -type d | while IFS= read -r d; do 
    cur_dir="${d##*/}"
    cmd="alias ${cur_dir}=\"code $d\""
    echo "executing: $cmd"
    $cmd
done

And the output looks like this:

executing: alias project-1="code /home/my_user/development/project-1"
./alias_for_projects.sh: line 6: alias: /home/my_user/development/project-1": not found
...

If I copy and run the command:

alias project-1="code /home/my_user/development/project-1"

it just works... How do I fix my script?

Kusalananda
  • 320,670
  • 36
  • 633
  • 936
Leo
  • 103
  • 4
  • @PauloTomé - your edit was incorrect! – Leo Apr 09 '20 at 11:12
  • Use an array to create the `cmd`, or better yet, just execute `alias "${cur_dir}"="code $d"` instead of running `$cmd` – muru Apr 09 '20 at 11:17
  • @muru - if I just `alias "${cur_dir}"="code $d"` when I then try to run `project-1` it returns `project-1: command not found` – Leo Apr 09 '20 at 11:21
  • To make your new aliases work outside of the while-loop, see [Modify global variable in while loop](https://unix.stackexchange.com/questions/402750/modify-global-variable-in-while-loop) – Freddy Apr 09 '20 at 11:25

2 Answers2

3

You have two problems:

  1. It's tricky to run a command stored in a variable. But you don't really need to store the command in a variable. You can just do alias "${cur_dir}"="code $d" where you run $cmd.

  2. You're running alias in subshell. Bash runs piped commands in a subshell (unless lastpipe is set). But you don't need the pipe (or find either). You can just use regular globbing (which you're already using, so the find makes even less sense).

Combined:

shopt -s dotglob
for d in ~/development/*/; do         # trailing slash - only directories match
    cur_dir="${d%/}"                  # strip trailing slash
    cur_dir="${cur_dir##*/}"
    alias "${cur_dir}"="code $d"
done
muru
  • 69,900
  • 13
  • 192
  • 292
0

After reading all comments, I fixed my script like this:

shopt -s dotglob #Use shopt -u dotglob to exclude hidden directories
while IFS= read -r d; do 
    cur_dir="${d##*/}"
    #echo "${cur_dir}"="code $d"
    alias "${cur_dir}"="code $d"
done <<<$(find ~/development/* -prune -type d)
Leo
  • 103
  • 4