I would like to know, if there is a way to go through a shell script and getting a warning for every command, that is unknown.

I know bash -n for syntax checking, but it doesn't tell me, if there are commands, that are not available.

Running the code is not an option, of course.


It's not possible in general, because a script can contain something like

read $command
"$command" -rf /

In real life, the command would be sanitized or picked from a list, but still, it's not possible to know in advance what commands are possible.

  • I'm afraid I don't quite follow. Could you elaborate, please? – Minix Nov 26 '14 at 14:52
  • @Minix: Without running a script, you can't tell what commands will be needed. – choroba Nov 26 '14 at 14:55
  • I can open the script and look inside, testing every command with type as @sputnick suggested in his answer. I was hoping, there was already a program or functions somewhere, doing just that. Are you saying you are not aware of such an application, or is there another prohibiting reason, that I'm missing right now? – Minix Nov 26 '14 at 15:00
  • 1
    @Minix: In the extreme example I gave in my reply, how can you check with type when you don't know what a user will type in? – choroba Nov 26 '14 at 15:02
  • 1
    @Minix his point is that "commands" can come from wherever. They can be stored in variables, they can be functions sourced from external files. They can be evaluated from other commands. How can you tell a script what is and what isn't a command? Also, essentially every line of a shell script is a command. – terdon Nov 26 '14 at 15:47

Try doing this explicitly :

test_apps="command1 command2 command3"
for cmd in $test_apps; do
    type &>/dev/null $cmd && echo "$cmd installed" ||
        echo >&2 "$cmd not installed"

Or if you put your commands with full PATHs :

grep -oP '^\s*/.*/\K.*' script.sh |
    xargs -I% which % 2>&1 |
    grep -oP '^\w+:\s+\Kno\s+\S+'
  • That would still leave the challenge of parsing out what in the script a command is and what normal syntax etc. – Minix Nov 26 '14 at 14:56
  • Added another solution, trying to test all commands with full PATHs – Gilles Quenot Nov 26 '14 at 15:00
  • That will still fail for commands that 1) are called by name and not path, 2) whose path has less than 2 / 3) that are called by relative paths (e.g. ~/bin/foo), 4) For all shell builtin commands. Also, it does not test things like $(command) etc. I don't think it is possible to do this simply. – terdon Nov 26 '14 at 16:03

I tend to do something like this:

if ! which dos2unix > /dev/null; then

   echo "Error: dos2unix not installed!"
   exit 1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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