2
\$\begingroup\$

The path is provided as an argument by a Makefile within an install target. The script verifies if the specified path is already included in the system's PATH variable. If it is not, the script prompts the user for confirmation to add the given path to the PATH. Upon receiving a positive response, it proceeds to append the specified path to the PATH variable. For instance, if the path /usr/local is provided, it will be added to the PATH variable after user confirmation.

#!/usr/bin/sh

# Check if kilo has been installed

set -e

program=kilo
expected="$(realpath "$1"/$program)"
echo "$PATH" | awk -v RS=: '{print $1 "/kilo" }'

for file in $(echo "$PATH" | awk -v RS=: '{print $1 "/$program" }'); do
    if [ ! -e "$file" ]; then
        continue
    fi

    if [ "$(realpath "$file")" = "$expected" ]; then
        exit 0
    fi
done

tput setaf 1
tput smso

1>&2 cat <<EOF
It appears that kilo was NOT installed successfully. Make sure that

  $1

is in your \$PATH. For example, if you are using the Bash shell, 
then you have to add

  export PATH="$1:\$PATH"

to your ~/.bashrc file.
EOF

tput sgr0

if [ -n "$ZSH_VERSION" ]; then
    shrc="$HOME/.zshrc"
elif [ -n "$BASH_VERSION" ]; then
    shrc="$HOME/.bashrc"
elif [ -n "FISH_VERSION" ]; then
    shrc="$HOME/.config/fish/config.fish"
fi

if [ -e "$shrc" ] && [ "$(tty)" != "not a tty" ]; then
    1>&2 printf "\nFix %s automatically (y/N)? " "$shrc"
    read -r IN
    if [ "$IN" = "y" ] || [ "$IN" = "Y" ]; then
        ed -s "$shrc" <<EOF
\$a

# look programs up in the local bin.
export PATH="$1:\$PATH"
.
wq
EOF
        1>&2 echo "Done, restart your shell to take effect."
        exit 0
    fi
fi

exit 1

Review Request:

Anything. Everything.

\$\endgroup\$

2 Answers 2

2
\$\begingroup\$
  • You don't want to edit the startup file of the current shell (by default, make invokes sh). You want to edit the user's default shell. Perhaps, $SHELL is a way to go. However, keep in mind that the startup file may not have a write permissions. If this is a case, act accordingly.

    BTW, the test omits a bunch of popular shells, such as csh, ksh, dash, plain old sh, etc.

  • I don't think that appending a lime to the startup file warrants invocation of ed.

      echo export PATH="$1:\$PATH" >> "$shrc"
    

    seems sufficient.

  • Along the same line, awk is also a heavy-duty tool. Consider an approach based on pure shell built-ins:

      IFS=: set $PATH
      for dir in $1; do
          [ -e "$dir/$progname" ]
          etc
      done
    
  • Why tinker with terminal settings? I think the script outsteps the mandate here. At the very least it shall restore the original settings (tput sgr0 does not do that - it clears attributes, but does not restore them.).

\$\endgroup\$
1
  • \$\begingroup\$ I was breaking all the entries in PATH, adding the program name to them, and checking if any matched the output of realpath. What would for dir in /usr/local; do do? \$\endgroup\$
    – Harith
    Commented Jun 27 at 6:48
2
\$\begingroup\$

hardcode

program=kilo
...
echo "$PATH" | awk -v RS=: '{print $1 "/kilo" }'

Please make that awk program look more like this subsequent one:

for file ... '{print $1 "/$program" }' ...

comments

# Check if kilo has been installed

This is accurate.

But the $PATH explanation given in the Review Context would fit nicely with this.

Consider breaking out the for file ... logic as a helper function, so we'll have a nice "if installed then we're cool, else we complain / fix".

You might possibly wish to leave e.g. a .bashrc.bak backup file lying around. If nothing else, it lets the user diff to see what changed.

testing

It's possible for someone to try out a shell they seldom use, and therefore lack a dot file for it. But we probably don't care about that corner case.

It appears you didn't test against the fish shell.

elif [ -n "FISH_VERSION" ]; then

Looks like you wanted $ dollar-sign interpolation in that expression.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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