0

in my ~/.bash_aliases i have a function:

function fresh() {

  if [ $# -eq 0 ] ; then
    # If no params added, source both bash_aliases and aliases.zsh
    "cp $HOME/.bash_aliases $ZSH_CUSTOM/aliases.zsh; source $HOME/.bash_aliases $ZSH_CUSTOM/aliases.zsh; echo 'Aliases Refreshed (Bash + Zsh).'"
    return 0
  fi

  CMD=$1
  shift

  case $CMD in
    b|bash)
      # Source bash_aliases (only)
      "source $HOME/.bash_aliases; echo 'Aliases Refreshed (Bash).'"
      ;;
    z|zsh|zash)
      # Source aliases.zsh (only)
      "source $ZSH_CUSTOM/aliases.zsh; echo 'Aliases Refreshed (Zsh).'"
      ;;
  esac
  return $?
}

The default fresh w/no args makes a copy of ~/.bash_aliases and just renames it to aliases.zsh, and then sources both files.

It worked fine as an actual alias, but moving it to a function I now get this:

fresh:4: no such file or directory: cp /home/scott/.bash_aliases /home/scott/.oh-my-zsh/custom/aliases.zsh; source /home/scott/.bash_aliases /home/scott/.oh-my-zsh/custom/aliases.zsh; echo 'Aliases Refreshed (Bash + Zsh).'

If I literally copy and paste each command from it, they work:

enter image description here

and changes confirmed by doing a cat $ZSH_CUSTOM/aliases.zsh and looking for the changes.

Any idea why it's complain that one of the files or dirs isn't found? Do I need to cd to some dir first? (seems like I shouldn't have to?)

J. Scott Elblein
  • 4,013
  • 15
  • 58
  • 94

1 Answers1

1

A command like "cp here there" will attempt to locate and run an executable file called, cp here there (the full command), it will not try to run cp with the here and there as arguments.

For example, the first ls command below works, the second does not (because it's not actually an ls command):

pax@styx> ls -ld /tmp
drwxrwxrwt 21 root root 4096 Mar 20 07:27 /tmp

pax@styx> "ls -ld /tmp"
-bash: ls -ld /tmp: No such file or directory

If you had "literally cop[ied] and paste[d] each command" including the quotes, you would have seen the same problem.

The solution, therefore, is to remove the " characters from the command, as well as the other similar commands within your case statement.

Just remember to quote the actual arguments (I always surround variables with {} as well) if there's a chance they could contain white space, such as with:

cp "${HOME}/.bash_aliases" "${ZSH_CUSTOM}/aliases.zsh"
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • 1
    I managed to solve my own problem just after posting. Still learning the ins and outs of bash quoting. This ended up working `cp "$HOME/.bash_aliases" "$ZSH_CUSTOM/aliases.zsh"; source "$HOME/.bash_aliases" "$ZSH_CUSTOM/aliases.zsh"; echo 'Aliases Refreshed (Bash + Zsh).'` – J. Scott Elblein Mar 19 '23 at 23:58
  • What's the benefit of always wrapping vars in braces? – J. Scott Elblein Mar 20 '23 at 00:12
  • 1
    @J.ScottElblein Braces around a variable reference are sometimes needed to disambiguate where the variable reference ends. For example, should `$variable` mean `${variable}`, `${v}ariable`, or `${var}iable`, etc? Similarly, should `$var/foo/bar` mean `${var}/foo/bar` or `${var/foo/bar}`? Even when they're not needed, braces can still be used for consistency and/or clarity. See ["When do we need curly braces around shell variables?"](https://stackoverflow.com/questions/8748831/when-do-we-need-curly-braces-around-shell-variables) – Gordon Davisson Mar 20 '23 at 00:25