Linux shell script: Run a program only if it exists, ignore it if it does not exist

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP












14















I am programming a Linux shell script that will print status banners during its execution only if the proper tool, say figlet, is installed (this is: reachable on system path).



Example:



#!/usr/bin/env bash
echo "foo"
figlet "Starting"
echo "moo"
figlet "Working"
echo "foo moo"
figlet "Finished"


I would like for my script to work without errors even when figlet is not installed.



What could be a practical method?










share|improve this question



















  • 1





    stackoverflow.com/questions/592620/…

    – gip
    Jan 29 at 19:22











  • @sudodus : just ignoring the 'figlet' (and its parameters) command would be OK. Continuing execution, of course.

    – Sopalajo de Arrierez
    Jan 30 at 10:50







  • 2





    The title to this question got me in all sorts of metaphysical problems

    – g_uint
    Jan 30 at 12:31






  • 2





    Do you want to ignore all errors? Just use figlet ... || true.

    – Giacomo Alzetta
    Jan 30 at 13:40











  • If you don’t care about exit codes a shortcut is to use figlet || true, but in your case probably a shell function which Echos plaintext If no Banner can be printed is more likely what you want.

    – eckes
    Jan 31 at 1:26















14















I am programming a Linux shell script that will print status banners during its execution only if the proper tool, say figlet, is installed (this is: reachable on system path).



Example:



#!/usr/bin/env bash
echo "foo"
figlet "Starting"
echo "moo"
figlet "Working"
echo "foo moo"
figlet "Finished"


I would like for my script to work without errors even when figlet is not installed.



What could be a practical method?










share|improve this question



















  • 1





    stackoverflow.com/questions/592620/…

    – gip
    Jan 29 at 19:22











  • @sudodus : just ignoring the 'figlet' (and its parameters) command would be OK. Continuing execution, of course.

    – Sopalajo de Arrierez
    Jan 30 at 10:50







  • 2





    The title to this question got me in all sorts of metaphysical problems

    – g_uint
    Jan 30 at 12:31






  • 2





    Do you want to ignore all errors? Just use figlet ... || true.

    – Giacomo Alzetta
    Jan 30 at 13:40











  • If you don’t care about exit codes a shortcut is to use figlet || true, but in your case probably a shell function which Echos plaintext If no Banner can be printed is more likely what you want.

    – eckes
    Jan 31 at 1:26













14












14








14


3






I am programming a Linux shell script that will print status banners during its execution only if the proper tool, say figlet, is installed (this is: reachable on system path).



Example:



#!/usr/bin/env bash
echo "foo"
figlet "Starting"
echo "moo"
figlet "Working"
echo "foo moo"
figlet "Finished"


I would like for my script to work without errors even when figlet is not installed.



What could be a practical method?










share|improve this question
















I am programming a Linux shell script that will print status banners during its execution only if the proper tool, say figlet, is installed (this is: reachable on system path).



Example:



#!/usr/bin/env bash
echo "foo"
figlet "Starting"
echo "moo"
figlet "Working"
echo "foo moo"
figlet "Finished"


I would like for my script to work without errors even when figlet is not installed.



What could be a practical method?







shell scripting executable






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 30 at 9:30









Gilles

538k12810881605




538k12810881605










asked Jan 29 at 19:11









Sopalajo de ArrierezSopalajo de Arrierez

1,75993563




1,75993563







  • 1





    stackoverflow.com/questions/592620/…

    – gip
    Jan 29 at 19:22











  • @sudodus : just ignoring the 'figlet' (and its parameters) command would be OK. Continuing execution, of course.

    – Sopalajo de Arrierez
    Jan 30 at 10:50







  • 2





    The title to this question got me in all sorts of metaphysical problems

    – g_uint
    Jan 30 at 12:31






  • 2





    Do you want to ignore all errors? Just use figlet ... || true.

    – Giacomo Alzetta
    Jan 30 at 13:40











  • If you don’t care about exit codes a shortcut is to use figlet || true, but in your case probably a shell function which Echos plaintext If no Banner can be printed is more likely what you want.

    – eckes
    Jan 31 at 1:26












  • 1





    stackoverflow.com/questions/592620/…

    – gip
    Jan 29 at 19:22











  • @sudodus : just ignoring the 'figlet' (and its parameters) command would be OK. Continuing execution, of course.

    – Sopalajo de Arrierez
    Jan 30 at 10:50







  • 2





    The title to this question got me in all sorts of metaphysical problems

    – g_uint
    Jan 30 at 12:31






  • 2





    Do you want to ignore all errors? Just use figlet ... || true.

    – Giacomo Alzetta
    Jan 30 at 13:40











  • If you don’t care about exit codes a shortcut is to use figlet || true, but in your case probably a shell function which Echos plaintext If no Banner can be printed is more likely what you want.

    – eckes
    Jan 31 at 1:26







1




1





stackoverflow.com/questions/592620/…

– gip
Jan 29 at 19:22





stackoverflow.com/questions/592620/…

– gip
Jan 29 at 19:22













@sudodus : just ignoring the 'figlet' (and its parameters) command would be OK. Continuing execution, of course.

– Sopalajo de Arrierez
Jan 30 at 10:50






@sudodus : just ignoring the 'figlet' (and its parameters) command would be OK. Continuing execution, of course.

– Sopalajo de Arrierez
Jan 30 at 10:50





2




2





The title to this question got me in all sorts of metaphysical problems

– g_uint
Jan 30 at 12:31





The title to this question got me in all sorts of metaphysical problems

– g_uint
Jan 30 at 12:31




2




2





Do you want to ignore all errors? Just use figlet ... || true.

– Giacomo Alzetta
Jan 30 at 13:40





Do you want to ignore all errors? Just use figlet ... || true.

– Giacomo Alzetta
Jan 30 at 13:40













If you don’t care about exit codes a shortcut is to use figlet || true, but in your case probably a shell function which Echos plaintext If no Banner can be printed is more likely what you want.

– eckes
Jan 31 at 1:26





If you don’t care about exit codes a shortcut is to use figlet || true, but in your case probably a shell function which Echos plaintext If no Banner can be printed is more likely what you want.

– eckes
Jan 31 at 1:26










8 Answers
8






active

oldest

votes


















28














My interpretation would use a wrapper function named the same as the tool; in that function, execute the real tool if it exists:



figlet() 
command -v figlet >/dev/null && command figlet "$@"



Then you can have figlet arg1 arg2... unchanged in your script.



@Olorin came up with a simpler method: define a wrapper function only if we need to (if the tool doesn't exist):



if ! command -v figlet > /dev/null; then figlet() :; ; fi


If you'd like the arguments to figlet to be printed even if figlet isn't installed, adjust Olorin's suggestion as follows:



if ! command -v figlet > /dev/null; then figlet() printf '%sn' "$*"; ; fi





share|improve this answer




















  • 1





    Where does command come from? I don't have it in my installations (Red Hat 6.8 Enterprise and Cygwin64).

    – eewanco
    Jan 29 at 22:38






  • 1





    @eewanco, see unix.stackexchange.com/a/85250/117549; long story short, it's built in to bash, which is probably your shell.

    – Jeff Schaller
    Jan 29 at 23:09







  • 3





    command is a POSIX Bourne shell builtin. It normally executes the command provided, but the -v flag makes it behave more like type, another shell builtin.

    – wyrm
    Jan 30 at 1:29











  • @eewanco type -a command will show you. which will only show executables on your $PATH, not built-ins, keywords, functions or aliases.

    – l0b0
    Jan 30 at 1:38












  • @l0b0: on RedHat-family with bash and the default profile(s) which does find an applicable alias, because it aliases which itself to run /usr/bin/which and pipe it a list of the shell's aliases to look in (!) (Of course which suppresses the alias and uses only the program, which doesn't show aliases.)

    – dave_thompson_085
    Jan 31 at 14:43



















14














You can test to see if figlet exists



if type figlet >/dev/null 2>&1
then
echo Figlet is installed
fi





share|improve this answer






























    6














    A common way to do this is with test -x aka [ -x. Here is an example taken from /etc/init.d/ntp on a Linux system:



    if [ -x /usr/bin/lockfile-create ]; then
    lockfile-create $LOCKFILE
    lockfile-touch $LOCKFILE &
    LOCKTOUCHPID="$!"
    fi


    This variant relies on knowing the full path of the executable. In /bin/lesspipe I found an example which works around that by combining -x and the which command:



    if [ -x "`which bunzip`" ]; then bunzip -c "$1"
    else echo "No bunzip available"; fi ;;


    That way this will work without knowing in advance where in the PATH the bunzip executable is.






    share|improve this answer




















    • 4





      Don't use which. And even if which worked, using test -x on its output is silly: if you get a path from which, it exists.

      – Gilles
      Jan 30 at 9:29






    • 1





      @Gilles: Technically speaking, test -x does more than just check if a file exists (that's what test -e is for). It also checks if the file has the execute permissions set.

      – comfreak
      Feb 1 at 19:19











    • @comfreak So does which.

      – Gilles
      Feb 1 at 20:25


















    5














    At the start of your script, check if figlet exists, and if it does not, define a shell function that does nothing:



    type figlet >/dev/null 2>&1 || figlet() :; 


    type checks if figlet exists as a shell built-in, function, alias, or keyword, >/dev/null 2>&1 discards stdin and stdout so you don't get any output, and if it does not exist, figlet() :; defines figlet as a function that does nothing.



    This way you don't have to edit every line of your script that uses figlet, or check if it exists every time figlet is called.



    You can add a diagnostic message, if you like:



    type figlet >/dev/null 2>&1 || echo 'figlet not installed.' ; figlet() :; ; 


    As a bonus, since you didn't mention which shell you are using, I believe this is POSIX compliant, so it should work on most any shell.






    share|improve this answer

























    • I like the simplicity of this answer. You could also replace type figlet >/dev/null 2>&1 with hash figlet 2>/dev/null if you're using bash. (The OP said "if it's in my PATH".)

      – Joe
      Feb 1 at 21:44


















    5














    Another alternative -- a pattern I've seen in project auto configure scripts:



    if [ -x /usr/bin/figlet ]
    then
    FIGLET=/usr/bin/figlet
    else
    FIGLET=:
    fi

    $FIGLET "Hello, world!"


    In your specific case you could even do,



    if [ -x /usr/bin/figlet ]
    then
    SAY=/usr/bin/figlet
    elif [ -x /usr/local/bin/figlet ]
    then
    SAY=/usr/local/bin/figlet
    elif [ -x /usr/bin/banner ]
    then
    SAY=/usr/bin/banner
    else
    SAY=/usr/bin/echo
    fi

    $SAY "Hello, world!"


    If you don't know the specific path, you can try multiple elif (see above) to try known locations, or just use the PATH to always resolve the command:



    if command -v figlet >/dev/null
    then
    SAY=figlet
    elif command -v banner >/dev/null
    then
    SAY=banner
    else
    SAY=echo
    fi


    In general, when writing scripts, I prefer to only call commands in specific locations specified by me. I don't like the uncertainty/risk of what the end user might have put into their PATH, perhaps in their own ~/bin.



    If, for example, I was writing a complicated script for others that might remove files based on the output of a particular command I'm calling, I wouldn't want to accidentally pick up something in their ~/bin that might or might not be the command I expected.






    share|improve this answer




















    • 3





      What if figlet was in /usr/local/bin or /home/bob/stuff/programs/executable/figlet?

      – Gilles
      Jan 30 at 9:30


















    3














    type -p figlet > /dev/null && figlet "foo"


    The bash type command finds a command, function, alias, keyword, or builtin (see help type) and prints out the location or definition. It also returns a return code representing the result of the search; true (0) if found. So what we're doing here is trying to find figlet in the path (-p means only look for files, not built-ins or functions, and also suppresses error messages), discarding output (that's what > /dev/null does), and if it returns true (&&), it will execute figlet.



    This is simpler if figlet is in a fixed location:



    [ -x /usr/bin/figlet ] && /usr/bin/figlet "foo"


    Here we're using the test command (a.k.a. [) to see if /usr/bin/figlet is executable (-x) and if so (&&) execute it. This solution I think is more portable than using type which is a bashism I believe.



    You could make a function that does this for you:



    function x() 
    if type -p "$1" >/dev/null; then
    cmd="$1"
    shift
    "$cmd" "$@"
    fi



    (The quotes are necessary owing to potential spaces)



    Then you'd just do:



    x figlet "foo"





    share|improve this answer
































      0














      o/,
      I would say something like



      #!/usr/bin/env bash
      # if figlet is installed :
      if [ "$(which figlet 2>/dev/null)" ]; then
      # do what you wanted to do
      echo "foo"
      figlet "Starting"
      echo "moo"
      figlet "Working"
      echo "foo moo"
      figlet "Finished"
      # if not
      else
      # exit program with an error
      echo "please install figlet"
      exit 1
      fi





      share|improve this answer






























        0














        You can do a test execution, suppressing any output, and test success/failure code. Choose arguments to figlet to make this test inexpensive. -? or --help or --version are obvious possibilities.



        if figlet --help >/dev/null 2>&1 ; then
        # figlet is available
        echo "foo"
        figlet "starting"
        #etc
        else
        rc=$?
        echo "figlet is not installed or not working correctly (return code $rc)"
        fi


        Added in response to comment below: if you really want to test that figlet exists, not that it's usable, then you would do



        figlet --help >/dev/null 2>&1 
        rc=$?
        if [ $rc -eq 127 ] ; then # 127 is "command not found" on linux bash 4.4.23(1)
        echo "command figlet not found"
        else
        figlet "whatever" # use figlet
        fi





        share|improve this answer

























        • The problem here is that figlet can fail for reasons besides not being installed, so just testing the exit code doesn't suffice.

          – Chris
          Jan 31 at 11:15











        • If you really want to test only for its installation, then you want to test if $? equals 127 (on my linux system). 127 is "command not found". But my thinking is that for rational commands, if command --help fails, then the installation is borked sufficiently that it might as well not be there!.

          – nigel222
          Jan 31 at 12:06







        • 1





          126 is "command found but not executable," so you would want to test against that as well. Unfortunately, you can't depend on --help being available. Posix utilities don't have it, for one, and posix guidelines actually recommend against it. at --help fails with at: invalid option -- '-', for instance, and an exit status of 130 on my system.

          – Chris
          Jan 31 at 12:47











        • Also, of course, if figlet can exit with status 127 that could be a problem too.

          – Chris
          Jan 31 at 15:14











        • Fair point about 126. Most sane utilities have some sort of lightweight harmless command options, such as -? --help --version ... or you could find out what figlet -0 --illegal exits with, and treat that as your success indicator (as long as it's not 127, which I would class as sabotage).

          – nigel222
          Jan 31 at 15:29











        Your Answer








        StackExchange.ready(function()
        var channelOptions =
        tags: "".split(" "),
        id: "106"
        ;
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function()
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled)
        StackExchange.using("snippets", function()
        createEditor();
        );

        else
        createEditor();

        );

        function createEditor()
        StackExchange.prepareEditor(
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: false,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: null,
        bindNavPrevention: true,
        postfix: "",
        imageUploader:
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        ,
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        );



        );













        draft saved

        draft discarded


















        StackExchange.ready(
        function ()
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f497526%2flinux-shell-script-run-a-program-only-if-it-exists-ignore-it-if-it-does-not-ex%23new-answer', 'question_page');

        );

        Post as a guest















        Required, but never shown

























        8 Answers
        8






        active

        oldest

        votes








        8 Answers
        8






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        28














        My interpretation would use a wrapper function named the same as the tool; in that function, execute the real tool if it exists:



        figlet() 
        command -v figlet >/dev/null && command figlet "$@"



        Then you can have figlet arg1 arg2... unchanged in your script.



        @Olorin came up with a simpler method: define a wrapper function only if we need to (if the tool doesn't exist):



        if ! command -v figlet > /dev/null; then figlet() :; ; fi


        If you'd like the arguments to figlet to be printed even if figlet isn't installed, adjust Olorin's suggestion as follows:



        if ! command -v figlet > /dev/null; then figlet() printf '%sn' "$*"; ; fi





        share|improve this answer




















        • 1





          Where does command come from? I don't have it in my installations (Red Hat 6.8 Enterprise and Cygwin64).

          – eewanco
          Jan 29 at 22:38






        • 1





          @eewanco, see unix.stackexchange.com/a/85250/117549; long story short, it's built in to bash, which is probably your shell.

          – Jeff Schaller
          Jan 29 at 23:09







        • 3





          command is a POSIX Bourne shell builtin. It normally executes the command provided, but the -v flag makes it behave more like type, another shell builtin.

          – wyrm
          Jan 30 at 1:29











        • @eewanco type -a command will show you. which will only show executables on your $PATH, not built-ins, keywords, functions or aliases.

          – l0b0
          Jan 30 at 1:38












        • @l0b0: on RedHat-family with bash and the default profile(s) which does find an applicable alias, because it aliases which itself to run /usr/bin/which and pipe it a list of the shell's aliases to look in (!) (Of course which suppresses the alias and uses only the program, which doesn't show aliases.)

          – dave_thompson_085
          Jan 31 at 14:43
















        28














        My interpretation would use a wrapper function named the same as the tool; in that function, execute the real tool if it exists:



        figlet() 
        command -v figlet >/dev/null && command figlet "$@"



        Then you can have figlet arg1 arg2... unchanged in your script.



        @Olorin came up with a simpler method: define a wrapper function only if we need to (if the tool doesn't exist):



        if ! command -v figlet > /dev/null; then figlet() :; ; fi


        If you'd like the arguments to figlet to be printed even if figlet isn't installed, adjust Olorin's suggestion as follows:



        if ! command -v figlet > /dev/null; then figlet() printf '%sn' "$*"; ; fi





        share|improve this answer




















        • 1





          Where does command come from? I don't have it in my installations (Red Hat 6.8 Enterprise and Cygwin64).

          – eewanco
          Jan 29 at 22:38






        • 1





          @eewanco, see unix.stackexchange.com/a/85250/117549; long story short, it's built in to bash, which is probably your shell.

          – Jeff Schaller
          Jan 29 at 23:09







        • 3





          command is a POSIX Bourne shell builtin. It normally executes the command provided, but the -v flag makes it behave more like type, another shell builtin.

          – wyrm
          Jan 30 at 1:29











        • @eewanco type -a command will show you. which will only show executables on your $PATH, not built-ins, keywords, functions or aliases.

          – l0b0
          Jan 30 at 1:38












        • @l0b0: on RedHat-family with bash and the default profile(s) which does find an applicable alias, because it aliases which itself to run /usr/bin/which and pipe it a list of the shell's aliases to look in (!) (Of course which suppresses the alias and uses only the program, which doesn't show aliases.)

          – dave_thompson_085
          Jan 31 at 14:43














        28












        28








        28







        My interpretation would use a wrapper function named the same as the tool; in that function, execute the real tool if it exists:



        figlet() 
        command -v figlet >/dev/null && command figlet "$@"



        Then you can have figlet arg1 arg2... unchanged in your script.



        @Olorin came up with a simpler method: define a wrapper function only if we need to (if the tool doesn't exist):



        if ! command -v figlet > /dev/null; then figlet() :; ; fi


        If you'd like the arguments to figlet to be printed even if figlet isn't installed, adjust Olorin's suggestion as follows:



        if ! command -v figlet > /dev/null; then figlet() printf '%sn' "$*"; ; fi





        share|improve this answer















        My interpretation would use a wrapper function named the same as the tool; in that function, execute the real tool if it exists:



        figlet() 
        command -v figlet >/dev/null && command figlet "$@"



        Then you can have figlet arg1 arg2... unchanged in your script.



        @Olorin came up with a simpler method: define a wrapper function only if we need to (if the tool doesn't exist):



        if ! command -v figlet > /dev/null; then figlet() :; ; fi


        If you'd like the arguments to figlet to be printed even if figlet isn't installed, adjust Olorin's suggestion as follows:



        if ! command -v figlet > /dev/null; then figlet() printf '%sn' "$*"; ; fi






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 31 at 14:53

























        answered Jan 29 at 20:20









        Jeff SchallerJeff Schaller

        41.7k1156132




        41.7k1156132







        • 1





          Where does command come from? I don't have it in my installations (Red Hat 6.8 Enterprise and Cygwin64).

          – eewanco
          Jan 29 at 22:38






        • 1





          @eewanco, see unix.stackexchange.com/a/85250/117549; long story short, it's built in to bash, which is probably your shell.

          – Jeff Schaller
          Jan 29 at 23:09







        • 3





          command is a POSIX Bourne shell builtin. It normally executes the command provided, but the -v flag makes it behave more like type, another shell builtin.

          – wyrm
          Jan 30 at 1:29











        • @eewanco type -a command will show you. which will only show executables on your $PATH, not built-ins, keywords, functions or aliases.

          – l0b0
          Jan 30 at 1:38












        • @l0b0: on RedHat-family with bash and the default profile(s) which does find an applicable alias, because it aliases which itself to run /usr/bin/which and pipe it a list of the shell's aliases to look in (!) (Of course which suppresses the alias and uses only the program, which doesn't show aliases.)

          – dave_thompson_085
          Jan 31 at 14:43













        • 1





          Where does command come from? I don't have it in my installations (Red Hat 6.8 Enterprise and Cygwin64).

          – eewanco
          Jan 29 at 22:38






        • 1





          @eewanco, see unix.stackexchange.com/a/85250/117549; long story short, it's built in to bash, which is probably your shell.

          – Jeff Schaller
          Jan 29 at 23:09







        • 3





          command is a POSIX Bourne shell builtin. It normally executes the command provided, but the -v flag makes it behave more like type, another shell builtin.

          – wyrm
          Jan 30 at 1:29











        • @eewanco type -a command will show you. which will only show executables on your $PATH, not built-ins, keywords, functions or aliases.

          – l0b0
          Jan 30 at 1:38












        • @l0b0: on RedHat-family with bash and the default profile(s) which does find an applicable alias, because it aliases which itself to run /usr/bin/which and pipe it a list of the shell's aliases to look in (!) (Of course which suppresses the alias and uses only the program, which doesn't show aliases.)

          – dave_thompson_085
          Jan 31 at 14:43








        1




        1





        Where does command come from? I don't have it in my installations (Red Hat 6.8 Enterprise and Cygwin64).

        – eewanco
        Jan 29 at 22:38





        Where does command come from? I don't have it in my installations (Red Hat 6.8 Enterprise and Cygwin64).

        – eewanco
        Jan 29 at 22:38




        1




        1





        @eewanco, see unix.stackexchange.com/a/85250/117549; long story short, it's built in to bash, which is probably your shell.

        – Jeff Schaller
        Jan 29 at 23:09






        @eewanco, see unix.stackexchange.com/a/85250/117549; long story short, it's built in to bash, which is probably your shell.

        – Jeff Schaller
        Jan 29 at 23:09





        3




        3





        command is a POSIX Bourne shell builtin. It normally executes the command provided, but the -v flag makes it behave more like type, another shell builtin.

        – wyrm
        Jan 30 at 1:29





        command is a POSIX Bourne shell builtin. It normally executes the command provided, but the -v flag makes it behave more like type, another shell builtin.

        – wyrm
        Jan 30 at 1:29













        @eewanco type -a command will show you. which will only show executables on your $PATH, not built-ins, keywords, functions or aliases.

        – l0b0
        Jan 30 at 1:38






        @eewanco type -a command will show you. which will only show executables on your $PATH, not built-ins, keywords, functions or aliases.

        – l0b0
        Jan 30 at 1:38














        @l0b0: on RedHat-family with bash and the default profile(s) which does find an applicable alias, because it aliases which itself to run /usr/bin/which and pipe it a list of the shell's aliases to look in (!) (Of course which suppresses the alias and uses only the program, which doesn't show aliases.)

        – dave_thompson_085
        Jan 31 at 14:43






        @l0b0: on RedHat-family with bash and the default profile(s) which does find an applicable alias, because it aliases which itself to run /usr/bin/which and pipe it a list of the shell's aliases to look in (!) (Of course which suppresses the alias and uses only the program, which doesn't show aliases.)

        – dave_thompson_085
        Jan 31 at 14:43














        14














        You can test to see if figlet exists



        if type figlet >/dev/null 2>&1
        then
        echo Figlet is installed
        fi





        share|improve this answer



























          14














          You can test to see if figlet exists



          if type figlet >/dev/null 2>&1
          then
          echo Figlet is installed
          fi





          share|improve this answer

























            14












            14








            14







            You can test to see if figlet exists



            if type figlet >/dev/null 2>&1
            then
            echo Figlet is installed
            fi





            share|improve this answer













            You can test to see if figlet exists



            if type figlet >/dev/null 2>&1
            then
            echo Figlet is installed
            fi






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Jan 29 at 19:16









            roaimaroaima

            44.8k755121




            44.8k755121





















                6














                A common way to do this is with test -x aka [ -x. Here is an example taken from /etc/init.d/ntp on a Linux system:



                if [ -x /usr/bin/lockfile-create ]; then
                lockfile-create $LOCKFILE
                lockfile-touch $LOCKFILE &
                LOCKTOUCHPID="$!"
                fi


                This variant relies on knowing the full path of the executable. In /bin/lesspipe I found an example which works around that by combining -x and the which command:



                if [ -x "`which bunzip`" ]; then bunzip -c "$1"
                else echo "No bunzip available"; fi ;;


                That way this will work without knowing in advance where in the PATH the bunzip executable is.






                share|improve this answer




















                • 4





                  Don't use which. And even if which worked, using test -x on its output is silly: if you get a path from which, it exists.

                  – Gilles
                  Jan 30 at 9:29






                • 1





                  @Gilles: Technically speaking, test -x does more than just check if a file exists (that's what test -e is for). It also checks if the file has the execute permissions set.

                  – comfreak
                  Feb 1 at 19:19











                • @comfreak So does which.

                  – Gilles
                  Feb 1 at 20:25















                6














                A common way to do this is with test -x aka [ -x. Here is an example taken from /etc/init.d/ntp on a Linux system:



                if [ -x /usr/bin/lockfile-create ]; then
                lockfile-create $LOCKFILE
                lockfile-touch $LOCKFILE &
                LOCKTOUCHPID="$!"
                fi


                This variant relies on knowing the full path of the executable. In /bin/lesspipe I found an example which works around that by combining -x and the which command:



                if [ -x "`which bunzip`" ]; then bunzip -c "$1"
                else echo "No bunzip available"; fi ;;


                That way this will work without knowing in advance where in the PATH the bunzip executable is.






                share|improve this answer




















                • 4





                  Don't use which. And even if which worked, using test -x on its output is silly: if you get a path from which, it exists.

                  – Gilles
                  Jan 30 at 9:29






                • 1





                  @Gilles: Technically speaking, test -x does more than just check if a file exists (that's what test -e is for). It also checks if the file has the execute permissions set.

                  – comfreak
                  Feb 1 at 19:19











                • @comfreak So does which.

                  – Gilles
                  Feb 1 at 20:25













                6












                6








                6







                A common way to do this is with test -x aka [ -x. Here is an example taken from /etc/init.d/ntp on a Linux system:



                if [ -x /usr/bin/lockfile-create ]; then
                lockfile-create $LOCKFILE
                lockfile-touch $LOCKFILE &
                LOCKTOUCHPID="$!"
                fi


                This variant relies on knowing the full path of the executable. In /bin/lesspipe I found an example which works around that by combining -x and the which command:



                if [ -x "`which bunzip`" ]; then bunzip -c "$1"
                else echo "No bunzip available"; fi ;;


                That way this will work without knowing in advance where in the PATH the bunzip executable is.






                share|improve this answer















                A common way to do this is with test -x aka [ -x. Here is an example taken from /etc/init.d/ntp on a Linux system:



                if [ -x /usr/bin/lockfile-create ]; then
                lockfile-create $LOCKFILE
                lockfile-touch $LOCKFILE &
                LOCKTOUCHPID="$!"
                fi


                This variant relies on knowing the full path of the executable. In /bin/lesspipe I found an example which works around that by combining -x and the which command:



                if [ -x "`which bunzip`" ]; then bunzip -c "$1"
                else echo "No bunzip available"; fi ;;


                That way this will work without knowing in advance where in the PATH the bunzip executable is.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Jan 30 at 10:08









                Greg A. Woods

                50237




                50237










                answered Jan 29 at 21:28









                kasperdkasperd

                2,45011127




                2,45011127







                • 4





                  Don't use which. And even if which worked, using test -x on its output is silly: if you get a path from which, it exists.

                  – Gilles
                  Jan 30 at 9:29






                • 1





                  @Gilles: Technically speaking, test -x does more than just check if a file exists (that's what test -e is for). It also checks if the file has the execute permissions set.

                  – comfreak
                  Feb 1 at 19:19











                • @comfreak So does which.

                  – Gilles
                  Feb 1 at 20:25












                • 4





                  Don't use which. And even if which worked, using test -x on its output is silly: if you get a path from which, it exists.

                  – Gilles
                  Jan 30 at 9:29






                • 1





                  @Gilles: Technically speaking, test -x does more than just check if a file exists (that's what test -e is for). It also checks if the file has the execute permissions set.

                  – comfreak
                  Feb 1 at 19:19











                • @comfreak So does which.

                  – Gilles
                  Feb 1 at 20:25







                4




                4





                Don't use which. And even if which worked, using test -x on its output is silly: if you get a path from which, it exists.

                – Gilles
                Jan 30 at 9:29





                Don't use which. And even if which worked, using test -x on its output is silly: if you get a path from which, it exists.

                – Gilles
                Jan 30 at 9:29




                1




                1





                @Gilles: Technically speaking, test -x does more than just check if a file exists (that's what test -e is for). It also checks if the file has the execute permissions set.

                – comfreak
                Feb 1 at 19:19





                @Gilles: Technically speaking, test -x does more than just check if a file exists (that's what test -e is for). It also checks if the file has the execute permissions set.

                – comfreak
                Feb 1 at 19:19













                @comfreak So does which.

                – Gilles
                Feb 1 at 20:25





                @comfreak So does which.

                – Gilles
                Feb 1 at 20:25











                5














                At the start of your script, check if figlet exists, and if it does not, define a shell function that does nothing:



                type figlet >/dev/null 2>&1 || figlet() :; 


                type checks if figlet exists as a shell built-in, function, alias, or keyword, >/dev/null 2>&1 discards stdin and stdout so you don't get any output, and if it does not exist, figlet() :; defines figlet as a function that does nothing.



                This way you don't have to edit every line of your script that uses figlet, or check if it exists every time figlet is called.



                You can add a diagnostic message, if you like:



                type figlet >/dev/null 2>&1 || echo 'figlet not installed.' ; figlet() :; ; 


                As a bonus, since you didn't mention which shell you are using, I believe this is POSIX compliant, so it should work on most any shell.






                share|improve this answer

























                • I like the simplicity of this answer. You could also replace type figlet >/dev/null 2>&1 with hash figlet 2>/dev/null if you're using bash. (The OP said "if it's in my PATH".)

                  – Joe
                  Feb 1 at 21:44















                5














                At the start of your script, check if figlet exists, and if it does not, define a shell function that does nothing:



                type figlet >/dev/null 2>&1 || figlet() :; 


                type checks if figlet exists as a shell built-in, function, alias, or keyword, >/dev/null 2>&1 discards stdin and stdout so you don't get any output, and if it does not exist, figlet() :; defines figlet as a function that does nothing.



                This way you don't have to edit every line of your script that uses figlet, or check if it exists every time figlet is called.



                You can add a diagnostic message, if you like:



                type figlet >/dev/null 2>&1 || echo 'figlet not installed.' ; figlet() :; ; 


                As a bonus, since you didn't mention which shell you are using, I believe this is POSIX compliant, so it should work on most any shell.






                share|improve this answer

























                • I like the simplicity of this answer. You could also replace type figlet >/dev/null 2>&1 with hash figlet 2>/dev/null if you're using bash. (The OP said "if it's in my PATH".)

                  – Joe
                  Feb 1 at 21:44













                5












                5








                5







                At the start of your script, check if figlet exists, and if it does not, define a shell function that does nothing:



                type figlet >/dev/null 2>&1 || figlet() :; 


                type checks if figlet exists as a shell built-in, function, alias, or keyword, >/dev/null 2>&1 discards stdin and stdout so you don't get any output, and if it does not exist, figlet() :; defines figlet as a function that does nothing.



                This way you don't have to edit every line of your script that uses figlet, or check if it exists every time figlet is called.



                You can add a diagnostic message, if you like:



                type figlet >/dev/null 2>&1 || echo 'figlet not installed.' ; figlet() :; ; 


                As a bonus, since you didn't mention which shell you are using, I believe this is POSIX compliant, so it should work on most any shell.






                share|improve this answer















                At the start of your script, check if figlet exists, and if it does not, define a shell function that does nothing:



                type figlet >/dev/null 2>&1 || figlet() :; 


                type checks if figlet exists as a shell built-in, function, alias, or keyword, >/dev/null 2>&1 discards stdin and stdout so you don't get any output, and if it does not exist, figlet() :; defines figlet as a function that does nothing.



                This way you don't have to edit every line of your script that uses figlet, or check if it exists every time figlet is called.



                You can add a diagnostic message, if you like:



                type figlet >/dev/null 2>&1 || echo 'figlet not installed.' ; figlet() :; ; 


                As a bonus, since you didn't mention which shell you are using, I believe this is POSIX compliant, so it should work on most any shell.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Jan 30 at 11:17

























                answered Jan 30 at 11:04









                ChrisChris

                1,120515




                1,120515












                • I like the simplicity of this answer. You could also replace type figlet >/dev/null 2>&1 with hash figlet 2>/dev/null if you're using bash. (The OP said "if it's in my PATH".)

                  – Joe
                  Feb 1 at 21:44

















                • I like the simplicity of this answer. You could also replace type figlet >/dev/null 2>&1 with hash figlet 2>/dev/null if you're using bash. (The OP said "if it's in my PATH".)

                  – Joe
                  Feb 1 at 21:44
















                I like the simplicity of this answer. You could also replace type figlet >/dev/null 2>&1 with hash figlet 2>/dev/null if you're using bash. (The OP said "if it's in my PATH".)

                – Joe
                Feb 1 at 21:44





                I like the simplicity of this answer. You could also replace type figlet >/dev/null 2>&1 with hash figlet 2>/dev/null if you're using bash. (The OP said "if it's in my PATH".)

                – Joe
                Feb 1 at 21:44











                5














                Another alternative -- a pattern I've seen in project auto configure scripts:



                if [ -x /usr/bin/figlet ]
                then
                FIGLET=/usr/bin/figlet
                else
                FIGLET=:
                fi

                $FIGLET "Hello, world!"


                In your specific case you could even do,



                if [ -x /usr/bin/figlet ]
                then
                SAY=/usr/bin/figlet
                elif [ -x /usr/local/bin/figlet ]
                then
                SAY=/usr/local/bin/figlet
                elif [ -x /usr/bin/banner ]
                then
                SAY=/usr/bin/banner
                else
                SAY=/usr/bin/echo
                fi

                $SAY "Hello, world!"


                If you don't know the specific path, you can try multiple elif (see above) to try known locations, or just use the PATH to always resolve the command:



                if command -v figlet >/dev/null
                then
                SAY=figlet
                elif command -v banner >/dev/null
                then
                SAY=banner
                else
                SAY=echo
                fi


                In general, when writing scripts, I prefer to only call commands in specific locations specified by me. I don't like the uncertainty/risk of what the end user might have put into their PATH, perhaps in their own ~/bin.



                If, for example, I was writing a complicated script for others that might remove files based on the output of a particular command I'm calling, I wouldn't want to accidentally pick up something in their ~/bin that might or might not be the command I expected.






                share|improve this answer




















                • 3





                  What if figlet was in /usr/local/bin or /home/bob/stuff/programs/executable/figlet?

                  – Gilles
                  Jan 30 at 9:30















                5














                Another alternative -- a pattern I've seen in project auto configure scripts:



                if [ -x /usr/bin/figlet ]
                then
                FIGLET=/usr/bin/figlet
                else
                FIGLET=:
                fi

                $FIGLET "Hello, world!"


                In your specific case you could even do,



                if [ -x /usr/bin/figlet ]
                then
                SAY=/usr/bin/figlet
                elif [ -x /usr/local/bin/figlet ]
                then
                SAY=/usr/local/bin/figlet
                elif [ -x /usr/bin/banner ]
                then
                SAY=/usr/bin/banner
                else
                SAY=/usr/bin/echo
                fi

                $SAY "Hello, world!"


                If you don't know the specific path, you can try multiple elif (see above) to try known locations, or just use the PATH to always resolve the command:



                if command -v figlet >/dev/null
                then
                SAY=figlet
                elif command -v banner >/dev/null
                then
                SAY=banner
                else
                SAY=echo
                fi


                In general, when writing scripts, I prefer to only call commands in specific locations specified by me. I don't like the uncertainty/risk of what the end user might have put into their PATH, perhaps in their own ~/bin.



                If, for example, I was writing a complicated script for others that might remove files based on the output of a particular command I'm calling, I wouldn't want to accidentally pick up something in their ~/bin that might or might not be the command I expected.






                share|improve this answer




















                • 3





                  What if figlet was in /usr/local/bin or /home/bob/stuff/programs/executable/figlet?

                  – Gilles
                  Jan 30 at 9:30













                5












                5








                5







                Another alternative -- a pattern I've seen in project auto configure scripts:



                if [ -x /usr/bin/figlet ]
                then
                FIGLET=/usr/bin/figlet
                else
                FIGLET=:
                fi

                $FIGLET "Hello, world!"


                In your specific case you could even do,



                if [ -x /usr/bin/figlet ]
                then
                SAY=/usr/bin/figlet
                elif [ -x /usr/local/bin/figlet ]
                then
                SAY=/usr/local/bin/figlet
                elif [ -x /usr/bin/banner ]
                then
                SAY=/usr/bin/banner
                else
                SAY=/usr/bin/echo
                fi

                $SAY "Hello, world!"


                If you don't know the specific path, you can try multiple elif (see above) to try known locations, or just use the PATH to always resolve the command:



                if command -v figlet >/dev/null
                then
                SAY=figlet
                elif command -v banner >/dev/null
                then
                SAY=banner
                else
                SAY=echo
                fi


                In general, when writing scripts, I prefer to only call commands in specific locations specified by me. I don't like the uncertainty/risk of what the end user might have put into their PATH, perhaps in their own ~/bin.



                If, for example, I was writing a complicated script for others that might remove files based on the output of a particular command I'm calling, I wouldn't want to accidentally pick up something in their ~/bin that might or might not be the command I expected.






                share|improve this answer















                Another alternative -- a pattern I've seen in project auto configure scripts:



                if [ -x /usr/bin/figlet ]
                then
                FIGLET=/usr/bin/figlet
                else
                FIGLET=:
                fi

                $FIGLET "Hello, world!"


                In your specific case you could even do,



                if [ -x /usr/bin/figlet ]
                then
                SAY=/usr/bin/figlet
                elif [ -x /usr/local/bin/figlet ]
                then
                SAY=/usr/local/bin/figlet
                elif [ -x /usr/bin/banner ]
                then
                SAY=/usr/bin/banner
                else
                SAY=/usr/bin/echo
                fi

                $SAY "Hello, world!"


                If you don't know the specific path, you can try multiple elif (see above) to try known locations, or just use the PATH to always resolve the command:



                if command -v figlet >/dev/null
                then
                SAY=figlet
                elif command -v banner >/dev/null
                then
                SAY=banner
                else
                SAY=echo
                fi


                In general, when writing scripts, I prefer to only call commands in specific locations specified by me. I don't like the uncertainty/risk of what the end user might have put into their PATH, perhaps in their own ~/bin.



                If, for example, I was writing a complicated script for others that might remove files based on the output of a particular command I'm calling, I wouldn't want to accidentally pick up something in their ~/bin that might or might not be the command I expected.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Feb 11 at 17:49

























                answered Jan 29 at 21:52









                rrauenzarrauenza

                42926




                42926







                • 3





                  What if figlet was in /usr/local/bin or /home/bob/stuff/programs/executable/figlet?

                  – Gilles
                  Jan 30 at 9:30












                • 3





                  What if figlet was in /usr/local/bin or /home/bob/stuff/programs/executable/figlet?

                  – Gilles
                  Jan 30 at 9:30







                3




                3





                What if figlet was in /usr/local/bin or /home/bob/stuff/programs/executable/figlet?

                – Gilles
                Jan 30 at 9:30





                What if figlet was in /usr/local/bin or /home/bob/stuff/programs/executable/figlet?

                – Gilles
                Jan 30 at 9:30











                3














                type -p figlet > /dev/null && figlet "foo"


                The bash type command finds a command, function, alias, keyword, or builtin (see help type) and prints out the location or definition. It also returns a return code representing the result of the search; true (0) if found. So what we're doing here is trying to find figlet in the path (-p means only look for files, not built-ins or functions, and also suppresses error messages), discarding output (that's what > /dev/null does), and if it returns true (&&), it will execute figlet.



                This is simpler if figlet is in a fixed location:



                [ -x /usr/bin/figlet ] && /usr/bin/figlet "foo"


                Here we're using the test command (a.k.a. [) to see if /usr/bin/figlet is executable (-x) and if so (&&) execute it. This solution I think is more portable than using type which is a bashism I believe.



                You could make a function that does this for you:



                function x() 
                if type -p "$1" >/dev/null; then
                cmd="$1"
                shift
                "$cmd" "$@"
                fi



                (The quotes are necessary owing to potential spaces)



                Then you'd just do:



                x figlet "foo"





                share|improve this answer





























                  3














                  type -p figlet > /dev/null && figlet "foo"


                  The bash type command finds a command, function, alias, keyword, or builtin (see help type) and prints out the location or definition. It also returns a return code representing the result of the search; true (0) if found. So what we're doing here is trying to find figlet in the path (-p means only look for files, not built-ins or functions, and also suppresses error messages), discarding output (that's what > /dev/null does), and if it returns true (&&), it will execute figlet.



                  This is simpler if figlet is in a fixed location:



                  [ -x /usr/bin/figlet ] && /usr/bin/figlet "foo"


                  Here we're using the test command (a.k.a. [) to see if /usr/bin/figlet is executable (-x) and if so (&&) execute it. This solution I think is more portable than using type which is a bashism I believe.



                  You could make a function that does this for you:



                  function x() 
                  if type -p "$1" >/dev/null; then
                  cmd="$1"
                  shift
                  "$cmd" "$@"
                  fi



                  (The quotes are necessary owing to potential spaces)



                  Then you'd just do:



                  x figlet "foo"





                  share|improve this answer



























                    3












                    3








                    3







                    type -p figlet > /dev/null && figlet "foo"


                    The bash type command finds a command, function, alias, keyword, or builtin (see help type) and prints out the location or definition. It also returns a return code representing the result of the search; true (0) if found. So what we're doing here is trying to find figlet in the path (-p means only look for files, not built-ins or functions, and also suppresses error messages), discarding output (that's what > /dev/null does), and if it returns true (&&), it will execute figlet.



                    This is simpler if figlet is in a fixed location:



                    [ -x /usr/bin/figlet ] && /usr/bin/figlet "foo"


                    Here we're using the test command (a.k.a. [) to see if /usr/bin/figlet is executable (-x) and if so (&&) execute it. This solution I think is more portable than using type which is a bashism I believe.



                    You could make a function that does this for you:



                    function x() 
                    if type -p "$1" >/dev/null; then
                    cmd="$1"
                    shift
                    "$cmd" "$@"
                    fi



                    (The quotes are necessary owing to potential spaces)



                    Then you'd just do:



                    x figlet "foo"





                    share|improve this answer















                    type -p figlet > /dev/null && figlet "foo"


                    The bash type command finds a command, function, alias, keyword, or builtin (see help type) and prints out the location or definition. It also returns a return code representing the result of the search; true (0) if found. So what we're doing here is trying to find figlet in the path (-p means only look for files, not built-ins or functions, and also suppresses error messages), discarding output (that's what > /dev/null does), and if it returns true (&&), it will execute figlet.



                    This is simpler if figlet is in a fixed location:



                    [ -x /usr/bin/figlet ] && /usr/bin/figlet "foo"


                    Here we're using the test command (a.k.a. [) to see if /usr/bin/figlet is executable (-x) and if so (&&) execute it. This solution I think is more portable than using type which is a bashism I believe.



                    You could make a function that does this for you:



                    function x() 
                    if type -p "$1" >/dev/null; then
                    cmd="$1"
                    shift
                    "$cmd" "$@"
                    fi



                    (The quotes are necessary owing to potential spaces)



                    Then you'd just do:



                    x figlet "foo"






                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Jan 29 at 22:26

























                    answered Jan 29 at 21:56









                    eewancoeewanco

                    295212




                    295212





















                        0














                        o/,
                        I would say something like



                        #!/usr/bin/env bash
                        # if figlet is installed :
                        if [ "$(which figlet 2>/dev/null)" ]; then
                        # do what you wanted to do
                        echo "foo"
                        figlet "Starting"
                        echo "moo"
                        figlet "Working"
                        echo "foo moo"
                        figlet "Finished"
                        # if not
                        else
                        # exit program with an error
                        echo "please install figlet"
                        exit 1
                        fi





                        share|improve this answer



























                          0














                          o/,
                          I would say something like



                          #!/usr/bin/env bash
                          # if figlet is installed :
                          if [ "$(which figlet 2>/dev/null)" ]; then
                          # do what you wanted to do
                          echo "foo"
                          figlet "Starting"
                          echo "moo"
                          figlet "Working"
                          echo "foo moo"
                          figlet "Finished"
                          # if not
                          else
                          # exit program with an error
                          echo "please install figlet"
                          exit 1
                          fi





                          share|improve this answer

























                            0












                            0








                            0







                            o/,
                            I would say something like



                            #!/usr/bin/env bash
                            # if figlet is installed :
                            if [ "$(which figlet 2>/dev/null)" ]; then
                            # do what you wanted to do
                            echo "foo"
                            figlet "Starting"
                            echo "moo"
                            figlet "Working"
                            echo "foo moo"
                            figlet "Finished"
                            # if not
                            else
                            # exit program with an error
                            echo "please install figlet"
                            exit 1
                            fi





                            share|improve this answer













                            o/,
                            I would say something like



                            #!/usr/bin/env bash
                            # if figlet is installed :
                            if [ "$(which figlet 2>/dev/null)" ]; then
                            # do what you wanted to do
                            echo "foo"
                            figlet "Starting"
                            echo "moo"
                            figlet "Working"
                            echo "foo moo"
                            figlet "Finished"
                            # if not
                            else
                            # exit program with an error
                            echo "please install figlet"
                            exit 1
                            fi






                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Jan 30 at 9:49









                            Jus de PatateJus de Patate

                            111




                            111





















                                0














                                You can do a test execution, suppressing any output, and test success/failure code. Choose arguments to figlet to make this test inexpensive. -? or --help or --version are obvious possibilities.



                                if figlet --help >/dev/null 2>&1 ; then
                                # figlet is available
                                echo "foo"
                                figlet "starting"
                                #etc
                                else
                                rc=$?
                                echo "figlet is not installed or not working correctly (return code $rc)"
                                fi


                                Added in response to comment below: if you really want to test that figlet exists, not that it's usable, then you would do



                                figlet --help >/dev/null 2>&1 
                                rc=$?
                                if [ $rc -eq 127 ] ; then # 127 is "command not found" on linux bash 4.4.23(1)
                                echo "command figlet not found"
                                else
                                figlet "whatever" # use figlet
                                fi





                                share|improve this answer

























                                • The problem here is that figlet can fail for reasons besides not being installed, so just testing the exit code doesn't suffice.

                                  – Chris
                                  Jan 31 at 11:15











                                • If you really want to test only for its installation, then you want to test if $? equals 127 (on my linux system). 127 is "command not found". But my thinking is that for rational commands, if command --help fails, then the installation is borked sufficiently that it might as well not be there!.

                                  – nigel222
                                  Jan 31 at 12:06







                                • 1





                                  126 is "command found but not executable," so you would want to test against that as well. Unfortunately, you can't depend on --help being available. Posix utilities don't have it, for one, and posix guidelines actually recommend against it. at --help fails with at: invalid option -- '-', for instance, and an exit status of 130 on my system.

                                  – Chris
                                  Jan 31 at 12:47











                                • Also, of course, if figlet can exit with status 127 that could be a problem too.

                                  – Chris
                                  Jan 31 at 15:14











                                • Fair point about 126. Most sane utilities have some sort of lightweight harmless command options, such as -? --help --version ... or you could find out what figlet -0 --illegal exits with, and treat that as your success indicator (as long as it's not 127, which I would class as sabotage).

                                  – nigel222
                                  Jan 31 at 15:29
















                                0














                                You can do a test execution, suppressing any output, and test success/failure code. Choose arguments to figlet to make this test inexpensive. -? or --help or --version are obvious possibilities.



                                if figlet --help >/dev/null 2>&1 ; then
                                # figlet is available
                                echo "foo"
                                figlet "starting"
                                #etc
                                else
                                rc=$?
                                echo "figlet is not installed or not working correctly (return code $rc)"
                                fi


                                Added in response to comment below: if you really want to test that figlet exists, not that it's usable, then you would do



                                figlet --help >/dev/null 2>&1 
                                rc=$?
                                if [ $rc -eq 127 ] ; then # 127 is "command not found" on linux bash 4.4.23(1)
                                echo "command figlet not found"
                                else
                                figlet "whatever" # use figlet
                                fi





                                share|improve this answer

























                                • The problem here is that figlet can fail for reasons besides not being installed, so just testing the exit code doesn't suffice.

                                  – Chris
                                  Jan 31 at 11:15











                                • If you really want to test only for its installation, then you want to test if $? equals 127 (on my linux system). 127 is "command not found". But my thinking is that for rational commands, if command --help fails, then the installation is borked sufficiently that it might as well not be there!.

                                  – nigel222
                                  Jan 31 at 12:06







                                • 1





                                  126 is "command found but not executable," so you would want to test against that as well. Unfortunately, you can't depend on --help being available. Posix utilities don't have it, for one, and posix guidelines actually recommend against it. at --help fails with at: invalid option -- '-', for instance, and an exit status of 130 on my system.

                                  – Chris
                                  Jan 31 at 12:47











                                • Also, of course, if figlet can exit with status 127 that could be a problem too.

                                  – Chris
                                  Jan 31 at 15:14











                                • Fair point about 126. Most sane utilities have some sort of lightweight harmless command options, such as -? --help --version ... or you could find out what figlet -0 --illegal exits with, and treat that as your success indicator (as long as it's not 127, which I would class as sabotage).

                                  – nigel222
                                  Jan 31 at 15:29














                                0












                                0








                                0







                                You can do a test execution, suppressing any output, and test success/failure code. Choose arguments to figlet to make this test inexpensive. -? or --help or --version are obvious possibilities.



                                if figlet --help >/dev/null 2>&1 ; then
                                # figlet is available
                                echo "foo"
                                figlet "starting"
                                #etc
                                else
                                rc=$?
                                echo "figlet is not installed or not working correctly (return code $rc)"
                                fi


                                Added in response to comment below: if you really want to test that figlet exists, not that it's usable, then you would do



                                figlet --help >/dev/null 2>&1 
                                rc=$?
                                if [ $rc -eq 127 ] ; then # 127 is "command not found" on linux bash 4.4.23(1)
                                echo "command figlet not found"
                                else
                                figlet "whatever" # use figlet
                                fi





                                share|improve this answer















                                You can do a test execution, suppressing any output, and test success/failure code. Choose arguments to figlet to make this test inexpensive. -? or --help or --version are obvious possibilities.



                                if figlet --help >/dev/null 2>&1 ; then
                                # figlet is available
                                echo "foo"
                                figlet "starting"
                                #etc
                                else
                                rc=$?
                                echo "figlet is not installed or not working correctly (return code $rc)"
                                fi


                                Added in response to comment below: if you really want to test that figlet exists, not that it's usable, then you would do



                                figlet --help >/dev/null 2>&1 
                                rc=$?
                                if [ $rc -eq 127 ] ; then # 127 is "command not found" on linux bash 4.4.23(1)
                                echo "command figlet not found"
                                else
                                figlet "whatever" # use figlet
                                fi






                                share|improve this answer














                                share|improve this answer



                                share|improve this answer








                                edited Jan 31 at 12:10

























                                answered Jan 31 at 10:50









                                nigel222nigel222

                                1514




                                1514












                                • The problem here is that figlet can fail for reasons besides not being installed, so just testing the exit code doesn't suffice.

                                  – Chris
                                  Jan 31 at 11:15











                                • If you really want to test only for its installation, then you want to test if $? equals 127 (on my linux system). 127 is "command not found". But my thinking is that for rational commands, if command --help fails, then the installation is borked sufficiently that it might as well not be there!.

                                  – nigel222
                                  Jan 31 at 12:06







                                • 1





                                  126 is "command found but not executable," so you would want to test against that as well. Unfortunately, you can't depend on --help being available. Posix utilities don't have it, for one, and posix guidelines actually recommend against it. at --help fails with at: invalid option -- '-', for instance, and an exit status of 130 on my system.

                                  – Chris
                                  Jan 31 at 12:47











                                • Also, of course, if figlet can exit with status 127 that could be a problem too.

                                  – Chris
                                  Jan 31 at 15:14











                                • Fair point about 126. Most sane utilities have some sort of lightweight harmless command options, such as -? --help --version ... or you could find out what figlet -0 --illegal exits with, and treat that as your success indicator (as long as it's not 127, which I would class as sabotage).

                                  – nigel222
                                  Jan 31 at 15:29


















                                • The problem here is that figlet can fail for reasons besides not being installed, so just testing the exit code doesn't suffice.

                                  – Chris
                                  Jan 31 at 11:15











                                • If you really want to test only for its installation, then you want to test if $? equals 127 (on my linux system). 127 is "command not found". But my thinking is that for rational commands, if command --help fails, then the installation is borked sufficiently that it might as well not be there!.

                                  – nigel222
                                  Jan 31 at 12:06







                                • 1





                                  126 is "command found but not executable," so you would want to test against that as well. Unfortunately, you can't depend on --help being available. Posix utilities don't have it, for one, and posix guidelines actually recommend against it. at --help fails with at: invalid option -- '-', for instance, and an exit status of 130 on my system.

                                  – Chris
                                  Jan 31 at 12:47











                                • Also, of course, if figlet can exit with status 127 that could be a problem too.

                                  – Chris
                                  Jan 31 at 15:14











                                • Fair point about 126. Most sane utilities have some sort of lightweight harmless command options, such as -? --help --version ... or you could find out what figlet -0 --illegal exits with, and treat that as your success indicator (as long as it's not 127, which I would class as sabotage).

                                  – nigel222
                                  Jan 31 at 15:29

















                                The problem here is that figlet can fail for reasons besides not being installed, so just testing the exit code doesn't suffice.

                                – Chris
                                Jan 31 at 11:15





                                The problem here is that figlet can fail for reasons besides not being installed, so just testing the exit code doesn't suffice.

                                – Chris
                                Jan 31 at 11:15













                                If you really want to test only for its installation, then you want to test if $? equals 127 (on my linux system). 127 is "command not found". But my thinking is that for rational commands, if command --help fails, then the installation is borked sufficiently that it might as well not be there!.

                                – nigel222
                                Jan 31 at 12:06






                                If you really want to test only for its installation, then you want to test if $? equals 127 (on my linux system). 127 is "command not found". But my thinking is that for rational commands, if command --help fails, then the installation is borked sufficiently that it might as well not be there!.

                                – nigel222
                                Jan 31 at 12:06





                                1




                                1





                                126 is "command found but not executable," so you would want to test against that as well. Unfortunately, you can't depend on --help being available. Posix utilities don't have it, for one, and posix guidelines actually recommend against it. at --help fails with at: invalid option -- '-', for instance, and an exit status of 130 on my system.

                                – Chris
                                Jan 31 at 12:47





                                126 is "command found but not executable," so you would want to test against that as well. Unfortunately, you can't depend on --help being available. Posix utilities don't have it, for one, and posix guidelines actually recommend against it. at --help fails with at: invalid option -- '-', for instance, and an exit status of 130 on my system.

                                – Chris
                                Jan 31 at 12:47













                                Also, of course, if figlet can exit with status 127 that could be a problem too.

                                – Chris
                                Jan 31 at 15:14





                                Also, of course, if figlet can exit with status 127 that could be a problem too.

                                – Chris
                                Jan 31 at 15:14













                                Fair point about 126. Most sane utilities have some sort of lightweight harmless command options, such as -? --help --version ... or you could find out what figlet -0 --illegal exits with, and treat that as your success indicator (as long as it's not 127, which I would class as sabotage).

                                – nigel222
                                Jan 31 at 15:29






                                Fair point about 126. Most sane utilities have some sort of lightweight harmless command options, such as -? --help --version ... or you could find out what figlet -0 --illegal exits with, and treat that as your success indicator (as long as it's not 127, which I would class as sabotage).

                                – nigel222
                                Jan 31 at 15:29


















                                draft saved

                                draft discarded
















































                                Thanks for contributing an answer to Unix & Linux Stack Exchange!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid


                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.

                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function ()
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f497526%2flinux-shell-script-run-a-program-only-if-it-exists-ignore-it-if-it-does-not-ex%23new-answer', 'question_page');

                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown






                                Popular posts from this blog

                                How to check contact read email or not when send email to Individual?

                                Bahrain

                                Postfix configuration issue with fips on centos 7; mailgun relay