9

When running this script:

#!/bin/sh -ex

if [[ $# -ne 1 ]]; then
  echo "./import-public-ssh-key.sh <absolute path to public key>"
  exit 1;
fi

PATH=$1
KEY=$(basename ${PATH})

I get:

./import-public-ssh-key.sh: line 9: basename: command not found

without the subshell basename works:

$ basename /Users/mles/.ssh/id_rsa.pub
id_rsa.pub

Why is basename not working in the subshell? I'm on a mac if this is relevant.

mles
  • 4,534
  • 10
  • 54
  • 94
  • 5
    `PATH` has special meaning. This is why you should use lowercase names for your own variables, to avoid overwriting ones that change shell or OS behavior by mistake. That is to say: `path=$1` won't risk any issues. – Charles Duffy Dec 29 '18 at 16:41
  • 1
    ...see http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html, fourth paragraph, where that convention is enshrined in POSIX. – Charles Duffy Dec 29 '18 at 16:42
  • 2
    As an aside, `sh -e` is... controversial; it can easily cause more bugs than it prevents, including oddly context-sensitive ones that evade easy attempts at testing. See [the exercises in BashFAQ #105](http://mywiki.wooledge.org/BashFAQ/105#Exercises) and the list of incompatibilities between different implementations at https://www.in-ulm.de/~mascheck/various/set-e/ before deciding to use it. – Charles Duffy Dec 29 '18 at 16:46
  • 2
    (Also, if you mean to be writing a *bash* script -- as implied by use of the bash tag here -- not a *sh* script, use `#!/bin/bash`, not `#!/bin/sh`, as your shebang; using a `sh` shebang doesn't guarantee you'll have any language features available except those given in the POSIX shell language spec). – Charles Duffy Dec 29 '18 at 16:48
  • 1
    (Also -- and this is my final comment, I promise -- you might consider making a habit of running your code through http://shellcheck.net/; in this case, it might have told you that you need to quote the expansion in the argument you're passing to `basename` -- thus, `key=$(basename "$path")` -- to work correctly with paths having spaces, or when IFS is otherwise set to contain characters that can exist inside your filenames; the curly braces make no difference here one way or the other, but quotes act to prevent string-splitting and glob expansion). – Charles Duffy Dec 29 '18 at 16:51
  • @CharlesDuffy: lowercase `path` has a special meaning in C-shell, but I guess we won't stoop *that* low. – cdarke Dec 29 '18 at 17:00
  • ...yeah, zsh sometimes breaks spec on that count as well, but... well, neither csh nor zsh *claim* to be POSIX-compliant shells. – Charles Duffy Dec 29 '18 at 17:00

1 Answers1

11

You reset the PATH. Don't do that. The shell searches all the directories listed in PATH, and you have changed it so that PATH no longer contains the directory that contains basename.

William Pursell
  • 204,365
  • 48
  • 270
  • 300