"basename" used in subshell returns "command not found" [duplicate]
Asked Answered
N

1

11

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.

Neufer answered 29/12, 2018 at 16:39 Comment(7)
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.Manamanacle
...see pubs.opengroup.org/onlinepubs/9699919799/basedefs/…, fourth paragraph, where that convention is enshrined in POSIX.Manamanacle
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 and the list of incompatibilities between different implementations at in-ulm.de/~mascheck/various/set-e before deciding to use it.Manamanacle
(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).Manamanacle
(Also -- and this is my final comment, I promise -- you might consider making a habit of running your code through 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).Manamanacle
@CharlesDuffy: lowercase path has a special meaning in C-shell, but I guess we won't stoop that low.Shoemaker
...yeah, zsh sometimes breaks spec on that count as well, but... well, neither csh nor zsh claim to be POSIX-compliant shells.Manamanacle
T
13

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.

Tague answered 29/12, 2018 at 16:41 Comment(2)
Answering a FAQ? Tsk, tsk.Manamanacle
ok well that was a seriously bad name for a variable :P thanks for the hintNeufer

© 2022 - 2024 — McMap. All rights reserved.