How to check if a shell is login/interactive/batch












127















I think I understand the differences between an interactive, a login and a batch shell. See the following links for more help:





  • What is the difference between a 'Login' and an 'Interactive' bash shell (from the sister site: serverfault.com)


  • 2.1: Types of shell: interactive and login shells (from A User's Guide to the Z-Shell)


My question is, how can I test with a command/condition if I am on an interactive, a login or a batch shell?



I am looking for a command or condition (that returns true or false) and that I could also place on an if statement. For example:



if [[ condition ]]
echo "This is a login shell"
fi









share|improve this question




















  • 2





    There is yet another question: Are STDIN and/or STDOUT connected to a tty (terminal) or a pipe (file or process)? This is a related but distinct test as described in some of the below comments.

    – Mark Hudson
    Oct 10 '14 at 18:04
















127















I think I understand the differences between an interactive, a login and a batch shell. See the following links for more help:





  • What is the difference between a 'Login' and an 'Interactive' bash shell (from the sister site: serverfault.com)


  • 2.1: Types of shell: interactive and login shells (from A User's Guide to the Z-Shell)


My question is, how can I test with a command/condition if I am on an interactive, a login or a batch shell?



I am looking for a command or condition (that returns true or false) and that I could also place on an if statement. For example:



if [[ condition ]]
echo "This is a login shell"
fi









share|improve this question




















  • 2





    There is yet another question: Are STDIN and/or STDOUT connected to a tty (terminal) or a pipe (file or process)? This is a related but distinct test as described in some of the below comments.

    – Mark Hudson
    Oct 10 '14 at 18:04














127












127








127


65






I think I understand the differences between an interactive, a login and a batch shell. See the following links for more help:





  • What is the difference between a 'Login' and an 'Interactive' bash shell (from the sister site: serverfault.com)


  • 2.1: Types of shell: interactive and login shells (from A User's Guide to the Z-Shell)


My question is, how can I test with a command/condition if I am on an interactive, a login or a batch shell?



I am looking for a command or condition (that returns true or false) and that I could also place on an if statement. For example:



if [[ condition ]]
echo "This is a login shell"
fi









share|improve this question
















I think I understand the differences between an interactive, a login and a batch shell. See the following links for more help:





  • What is the difference between a 'Login' and an 'Interactive' bash shell (from the sister site: serverfault.com)


  • 2.1: Types of shell: interactive and login shells (from A User's Guide to the Z-Shell)


My question is, how can I test with a command/condition if I am on an interactive, a login or a batch shell?



I am looking for a command or condition (that returns true or false) and that I could also place on an if statement. For example:



if [[ condition ]]
echo "This is a login shell"
fi






shell






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Apr 13 '17 at 12:13









Community

1




1










asked Dec 13 '11 at 1:31









Amelio Vazquez-ReinaAmelio Vazquez-Reina

12.8k54138237




12.8k54138237








  • 2





    There is yet another question: Are STDIN and/or STDOUT connected to a tty (terminal) or a pipe (file or process)? This is a related but distinct test as described in some of the below comments.

    – Mark Hudson
    Oct 10 '14 at 18:04














  • 2





    There is yet another question: Are STDIN and/or STDOUT connected to a tty (terminal) or a pipe (file or process)? This is a related but distinct test as described in some of the below comments.

    – Mark Hudson
    Oct 10 '14 at 18:04








2




2





There is yet another question: Are STDIN and/or STDOUT connected to a tty (terminal) or a pipe (file or process)? This is a related but distinct test as described in some of the below comments.

– Mark Hudson
Oct 10 '14 at 18:04





There is yet another question: Are STDIN and/or STDOUT connected to a tty (terminal) or a pipe (file or process)? This is a related but distinct test as described in some of the below comments.

– Mark Hudson
Oct 10 '14 at 18:04










10 Answers
10






active

oldest

votes


















140














I'm assuming a bash shell, or similar, since there is no shell listed in the tags.



To check if you are in an interactive shell:



[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'


To check if you are in a login shell:



shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'


By "batch", I assume you mean "not interactive", so the check for an interactive shell should suffice.






share|improve this answer



















  • 12





    For zsh users, checking for a login shell can be done with: if [[ -o login ]] ...

    – chb
    Jun 27 '13 at 5:05








  • 1





    If you want to know if a "user" ran your program versus "cron". [[ TERM=="dumb" ]] && echo "Running in cron.

    – Erik Aronesty
    Dec 3 '13 at 17:49








  • 10





    @ErikAronesty Not all dumb terminals are cron sessions.

    – Chris Down
    Dec 4 '13 at 22:11






  • 2





    “I'm assuming a bash shell, or similar, since there is no shell listed in the tags.” – The logic of this statement is truly beautiful! :)

    – Michael Le Barbier Grünewald
    Dec 14 '15 at 8:44






  • 1





    @antonio That's because your quoting is wrong, $- is being expanded in the current shell. If you use single quotes around the full expression you will get the correct result: bash -c '[[ $- == *i* ]] && echo "Interactive" || echo "Not interactive"'

    – Chris Down
    Jun 1 '16 at 15:58



















30














In any Bourne-style shell, the i option indicates whether the shell is interactive:



case $- in
*i*) echo "This shell is interactive";;
*) echo "This is a script";;
esac


There's no portable and fully reliable way to test for a login shell. Ksh and zsh add l to $-. Bash sets the login_shell option, which you can query with shopt -q login_shell. Portably, test whether $0 starts with a -: shells normally know that they're login shells because the caller added a - prefix to argument zero (normally the name or path of the executable). This fails to detect shell-specific ways of invoking a login shell (e.g. ash -l).






share|improve this answer


























  • (...) because the caller – I think there's something missing in this fragment.

    – Piotr Dobrogost
    Jul 20 '15 at 12:22













  • It would be ideal if $0 always starts with a - no matter how it was started. But there is at least one exception: This is not always true with bash even if it is supposed to be a login shell. Try it in your box: invoke bash --login, then $0 still reads bash.

    – Wirawan Purwanto
    Oct 16 '15 at 20:35











  • @WirawanPurwanto I'm not sure I understand your comment. Isn't that what I wrote in my last sentence?

    – Gilles
    Oct 18 '15 at 19:19











  • @Gilles: You are correct. Sorry I missed your last sentence.

    – Wirawan Purwanto
    Oct 20 '15 at 17:58



















22














fish shell



Here's the answer for fish in case any other users stumble upon this page.



if status --is-interactive
# ...
end

if status --is-login
# ...
end

echo "darn, I really wanted to have to use globs or at least a case statement"


Fish documentation: initialization






share|improve this answer





















  • 1





    -1 for unnecessary editorializing.

    – Nick Bastin
    Aug 20 '15 at 17:22






  • 6





    If anyone wonders at @NickBastin's comment, he had a fair point so I made an edit. The original amount of snarkiness has now been cut in half.

    – ohspite
    Aug 21 '15 at 3:56



















16














csh / tcsh



For csh and tcsh I have the following in my .cshrc file:



if($?prompt) then               # Only interactive shells set $prompt
...
endif


Specifically for tcsh, the variable loginsh is set for a login shell:



if($?loginsh) then              # A login shell..
...
endif


(tcsh also has a variable shlvl which is set to the number of nested shells, where the login shell has a value of 1.)






share|improve this answer





















  • 2





    PS1 does not work to test for an interactive shell. It's almost always set in an interactive, but you can unset it. It's very often set in a noninteractive shell, because many systems ship with export PS in /etc/profile.

    – Gilles
    Dec 14 '11 at 11:35











  • @Gilles Thank you for the correction and edit

    – Andrew Stein
    Dec 14 '11 at 15:26



















13














Another way is to check the result of tty



if [ "`tty`" != "not a tty" ]; then





share|improve this answer





















  • 10





    ... or use [ -t 0 ] to test if STDIN is a tty. You can also use 1 (STDOUT) or 2 (STDERR) depending on your needs.

    – derobert
    Dec 13 '11 at 23:17













  • @derobert - thanks for showing me something new

    – Adrian Cornish
    Dec 14 '11 at 3:12






  • 9





    This is a different test. It is possible to have a noninteractive shell whose input is a terminal (anytime you run a script in a terminal!), and it is possible (albeit rare) to have an interactive shell taking input not from a terminal.

    – Gilles
    Dec 14 '11 at 11:34











  • @Gilles if the shell was interactive, and closed leaving a child disown and alive, tty worked best to know it is not interactive anymore, while $- did not change; I am still puzzled about what is the best approach.

    – Aquarius Power
    Jul 25 '14 at 6:14






  • 5





    @AquariusPower Then what you want to test is not for an interactive shell, but whether standard input is a terminal. Use [ -t 0 ]. P.S. In my previous comment, I wrote that “there's a strong correlation” — I forgot “apart from the extremely common case of a script started with #!/bin/sh or the like”, which is non-interactive but can be connected to a terminal.

    – Gilles
    Jul 25 '14 at 7:55





















6














UNIX/Linux has a command to check if you are on a terminal.



if tty -s
then
echo Terminal
else
echo Not on a terminal
fi





share|improve this answer



















  • 1





    This works in dash also.

    – Ken Sharp
    Nov 30 '17 at 12:27



















6














You can check to see if stdin is a terminal:



if [ -t 0 ]
then
echo "Hit enter"
read ans
fi





share|improve this answer

































    1














    Take a look at the shopt command (at least for Bash).
    That can definitely tell you if you're in a login shell. I don't know about interactive/batch.



    Reference: http://www.linuxquestions.org/questions/programming-9/how-to-check-in-a-script-whether-the-shell-is-login-or-non-login-360629/



    Look in the Bash man page for more info: http://linux.die.net/man/1/bash



    Note: I am giving you Bash, since that's what I know. Presumably other shells have similar functionality.






    share|improve this answer































      1














      To check whether a script runs in an interactive or non-interactive shell,
      I check in my scripts for the presence of a prompt stored in the $PS1 variable:



      if [ -z $PS1 ] # no prompt?
      ### if [ -v PS1 ] # On Bash 4.2+ ...
      then
      # non-interactive
      ...
      else
      # interactive
      ...
      fi


      This I learned here: https://www.tldp.org/LDP/abs/html/intandnonint.html






      share|improve this answer































        0














        i is not the correct option to look for. -i is to force an otherwise
        non-interactive shell to become interactive. The correct auto-enabled
        option is -s, but Bash unfortunately does not handle this correctly.



        You need to check whether $- contains s (this is granted to be
        auto-activated) or whether it contains i (this is not granted to
        be auto-activated but officially only coupled to the -i command line
        option of the shell).






        share|improve this answer


























        • s would be if the shell reads commands from stdin, not whether it's interactive. An interactive shell does not necessarily read commands from stdin (try zsh -i < /dev/null, though zsh seems to be the exception here). And a shell may be reading commands from stdin and not be interactive (like sh < file or echo 'echo "$1"' | sh -s foo bar).

          – Stéphane Chazelas
          Aug 18 '15 at 13:59






        • 1





          What I wanted to point out is that the original Bourne Shell does not have 'i' in $-, even when it is intended to be interactive.

          – schily
          Aug 18 '15 at 14:07











        • OK, but on U&L, "shell" tend to refer to modern shells. The Bourne shell is generally considered a relique and your own variant is not mainstream enough to expect people to know what you're talking about unless you make it explicit. The question mentioned [[...]] which implies ksh/bash/zsh. You've got a point as a history note that checking for i in $- won't work in the Bourne shell. But then checking for s won't work there reliably either. You'd want to also check for [ -t 0 ] or i; even then that'd be fooled in corner cases like echo 'exec < /dev/tty; that-check' | sh'

          – Stéphane Chazelas
          Aug 18 '15 at 14:24













        • Solaris up to Solaris 10 come with the original Bourne Shell and even sill includes aprox. 10 bugs known to be in the shell since SVr4. So adding a hint on the Bourne Shell is not hat deviously as you might belive. zsh on the other side is not sufficient compatible, it e.g. fails when you try to run "configure" with zsh, so beware to set up /bin/sh to point to zsh. BTW: my Bourne Shell sets -i by default in case it decides to be interactive.

          – schily
          Aug 18 '15 at 14:30






        • 1





          I notice POSIX doesn't seem to require $- contain i (which it seems to require s), I'll raise the question on the austin-group ML.

          – Stéphane Chazelas
          Aug 18 '15 at 15:09











        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%2f26676%2fhow-to-check-if-a-shell-is-login-interactive-batch%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        10 Answers
        10






        active

        oldest

        votes








        10 Answers
        10






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        140














        I'm assuming a bash shell, or similar, since there is no shell listed in the tags.



        To check if you are in an interactive shell:



        [[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'


        To check if you are in a login shell:



        shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'


        By "batch", I assume you mean "not interactive", so the check for an interactive shell should suffice.






        share|improve this answer



















        • 12





          For zsh users, checking for a login shell can be done with: if [[ -o login ]] ...

          – chb
          Jun 27 '13 at 5:05








        • 1





          If you want to know if a "user" ran your program versus "cron". [[ TERM=="dumb" ]] && echo "Running in cron.

          – Erik Aronesty
          Dec 3 '13 at 17:49








        • 10





          @ErikAronesty Not all dumb terminals are cron sessions.

          – Chris Down
          Dec 4 '13 at 22:11






        • 2





          “I'm assuming a bash shell, or similar, since there is no shell listed in the tags.” – The logic of this statement is truly beautiful! :)

          – Michael Le Barbier Grünewald
          Dec 14 '15 at 8:44






        • 1





          @antonio That's because your quoting is wrong, $- is being expanded in the current shell. If you use single quotes around the full expression you will get the correct result: bash -c '[[ $- == *i* ]] && echo "Interactive" || echo "Not interactive"'

          – Chris Down
          Jun 1 '16 at 15:58
















        140














        I'm assuming a bash shell, or similar, since there is no shell listed in the tags.



        To check if you are in an interactive shell:



        [[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'


        To check if you are in a login shell:



        shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'


        By "batch", I assume you mean "not interactive", so the check for an interactive shell should suffice.






        share|improve this answer



















        • 12





          For zsh users, checking for a login shell can be done with: if [[ -o login ]] ...

          – chb
          Jun 27 '13 at 5:05








        • 1





          If you want to know if a "user" ran your program versus "cron". [[ TERM=="dumb" ]] && echo "Running in cron.

          – Erik Aronesty
          Dec 3 '13 at 17:49








        • 10





          @ErikAronesty Not all dumb terminals are cron sessions.

          – Chris Down
          Dec 4 '13 at 22:11






        • 2





          “I'm assuming a bash shell, or similar, since there is no shell listed in the tags.” – The logic of this statement is truly beautiful! :)

          – Michael Le Barbier Grünewald
          Dec 14 '15 at 8:44






        • 1





          @antonio That's because your quoting is wrong, $- is being expanded in the current shell. If you use single quotes around the full expression you will get the correct result: bash -c '[[ $- == *i* ]] && echo "Interactive" || echo "Not interactive"'

          – Chris Down
          Jun 1 '16 at 15:58














        140












        140








        140







        I'm assuming a bash shell, or similar, since there is no shell listed in the tags.



        To check if you are in an interactive shell:



        [[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'


        To check if you are in a login shell:



        shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'


        By "batch", I assume you mean "not interactive", so the check for an interactive shell should suffice.






        share|improve this answer













        I'm assuming a bash shell, or similar, since there is no shell listed in the tags.



        To check if you are in an interactive shell:



        [[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'


        To check if you are in a login shell:



        shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'


        By "batch", I assume you mean "not interactive", so the check for an interactive shell should suffice.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Dec 13 '11 at 23:19









        Chris DownChris Down

        81.1k15189203




        81.1k15189203








        • 12





          For zsh users, checking for a login shell can be done with: if [[ -o login ]] ...

          – chb
          Jun 27 '13 at 5:05








        • 1





          If you want to know if a "user" ran your program versus "cron". [[ TERM=="dumb" ]] && echo "Running in cron.

          – Erik Aronesty
          Dec 3 '13 at 17:49








        • 10





          @ErikAronesty Not all dumb terminals are cron sessions.

          – Chris Down
          Dec 4 '13 at 22:11






        • 2





          “I'm assuming a bash shell, or similar, since there is no shell listed in the tags.” – The logic of this statement is truly beautiful! :)

          – Michael Le Barbier Grünewald
          Dec 14 '15 at 8:44






        • 1





          @antonio That's because your quoting is wrong, $- is being expanded in the current shell. If you use single quotes around the full expression you will get the correct result: bash -c '[[ $- == *i* ]] && echo "Interactive" || echo "Not interactive"'

          – Chris Down
          Jun 1 '16 at 15:58














        • 12





          For zsh users, checking for a login shell can be done with: if [[ -o login ]] ...

          – chb
          Jun 27 '13 at 5:05








        • 1





          If you want to know if a "user" ran your program versus "cron". [[ TERM=="dumb" ]] && echo "Running in cron.

          – Erik Aronesty
          Dec 3 '13 at 17:49








        • 10





          @ErikAronesty Not all dumb terminals are cron sessions.

          – Chris Down
          Dec 4 '13 at 22:11






        • 2





          “I'm assuming a bash shell, or similar, since there is no shell listed in the tags.” – The logic of this statement is truly beautiful! :)

          – Michael Le Barbier Grünewald
          Dec 14 '15 at 8:44






        • 1





          @antonio That's because your quoting is wrong, $- is being expanded in the current shell. If you use single quotes around the full expression you will get the correct result: bash -c '[[ $- == *i* ]] && echo "Interactive" || echo "Not interactive"'

          – Chris Down
          Jun 1 '16 at 15:58








        12




        12





        For zsh users, checking for a login shell can be done with: if [[ -o login ]] ...

        – chb
        Jun 27 '13 at 5:05







        For zsh users, checking for a login shell can be done with: if [[ -o login ]] ...

        – chb
        Jun 27 '13 at 5:05






        1




        1





        If you want to know if a "user" ran your program versus "cron". [[ TERM=="dumb" ]] && echo "Running in cron.

        – Erik Aronesty
        Dec 3 '13 at 17:49







        If you want to know if a "user" ran your program versus "cron". [[ TERM=="dumb" ]] && echo "Running in cron.

        – Erik Aronesty
        Dec 3 '13 at 17:49






        10




        10





        @ErikAronesty Not all dumb terminals are cron sessions.

        – Chris Down
        Dec 4 '13 at 22:11





        @ErikAronesty Not all dumb terminals are cron sessions.

        – Chris Down
        Dec 4 '13 at 22:11




        2




        2





        “I'm assuming a bash shell, or similar, since there is no shell listed in the tags.” – The logic of this statement is truly beautiful! :)

        – Michael Le Barbier Grünewald
        Dec 14 '15 at 8:44





        “I'm assuming a bash shell, or similar, since there is no shell listed in the tags.” – The logic of this statement is truly beautiful! :)

        – Michael Le Barbier Grünewald
        Dec 14 '15 at 8:44




        1




        1





        @antonio That's because your quoting is wrong, $- is being expanded in the current shell. If you use single quotes around the full expression you will get the correct result: bash -c '[[ $- == *i* ]] && echo "Interactive" || echo "Not interactive"'

        – Chris Down
        Jun 1 '16 at 15:58





        @antonio That's because your quoting is wrong, $- is being expanded in the current shell. If you use single quotes around the full expression you will get the correct result: bash -c '[[ $- == *i* ]] && echo "Interactive" || echo "Not interactive"'

        – Chris Down
        Jun 1 '16 at 15:58













        30














        In any Bourne-style shell, the i option indicates whether the shell is interactive:



        case $- in
        *i*) echo "This shell is interactive";;
        *) echo "This is a script";;
        esac


        There's no portable and fully reliable way to test for a login shell. Ksh and zsh add l to $-. Bash sets the login_shell option, which you can query with shopt -q login_shell. Portably, test whether $0 starts with a -: shells normally know that they're login shells because the caller added a - prefix to argument zero (normally the name or path of the executable). This fails to detect shell-specific ways of invoking a login shell (e.g. ash -l).






        share|improve this answer


























        • (...) because the caller – I think there's something missing in this fragment.

          – Piotr Dobrogost
          Jul 20 '15 at 12:22













        • It would be ideal if $0 always starts with a - no matter how it was started. But there is at least one exception: This is not always true with bash even if it is supposed to be a login shell. Try it in your box: invoke bash --login, then $0 still reads bash.

          – Wirawan Purwanto
          Oct 16 '15 at 20:35











        • @WirawanPurwanto I'm not sure I understand your comment. Isn't that what I wrote in my last sentence?

          – Gilles
          Oct 18 '15 at 19:19











        • @Gilles: You are correct. Sorry I missed your last sentence.

          – Wirawan Purwanto
          Oct 20 '15 at 17:58
















        30














        In any Bourne-style shell, the i option indicates whether the shell is interactive:



        case $- in
        *i*) echo "This shell is interactive";;
        *) echo "This is a script";;
        esac


        There's no portable and fully reliable way to test for a login shell. Ksh and zsh add l to $-. Bash sets the login_shell option, which you can query with shopt -q login_shell. Portably, test whether $0 starts with a -: shells normally know that they're login shells because the caller added a - prefix to argument zero (normally the name or path of the executable). This fails to detect shell-specific ways of invoking a login shell (e.g. ash -l).






        share|improve this answer


























        • (...) because the caller – I think there's something missing in this fragment.

          – Piotr Dobrogost
          Jul 20 '15 at 12:22













        • It would be ideal if $0 always starts with a - no matter how it was started. But there is at least one exception: This is not always true with bash even if it is supposed to be a login shell. Try it in your box: invoke bash --login, then $0 still reads bash.

          – Wirawan Purwanto
          Oct 16 '15 at 20:35











        • @WirawanPurwanto I'm not sure I understand your comment. Isn't that what I wrote in my last sentence?

          – Gilles
          Oct 18 '15 at 19:19











        • @Gilles: You are correct. Sorry I missed your last sentence.

          – Wirawan Purwanto
          Oct 20 '15 at 17:58














        30












        30








        30







        In any Bourne-style shell, the i option indicates whether the shell is interactive:



        case $- in
        *i*) echo "This shell is interactive";;
        *) echo "This is a script";;
        esac


        There's no portable and fully reliable way to test for a login shell. Ksh and zsh add l to $-. Bash sets the login_shell option, which you can query with shopt -q login_shell. Portably, test whether $0 starts with a -: shells normally know that they're login shells because the caller added a - prefix to argument zero (normally the name or path of the executable). This fails to detect shell-specific ways of invoking a login shell (e.g. ash -l).






        share|improve this answer















        In any Bourne-style shell, the i option indicates whether the shell is interactive:



        case $- in
        *i*) echo "This shell is interactive";;
        *) echo "This is a script";;
        esac


        There's no portable and fully reliable way to test for a login shell. Ksh and zsh add l to $-. Bash sets the login_shell option, which you can query with shopt -q login_shell. Portably, test whether $0 starts with a -: shells normally know that they're login shells because the caller added a - prefix to argument zero (normally the name or path of the executable). This fails to detect shell-specific ways of invoking a login shell (e.g. ash -l).







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jul 20 '15 at 12:30

























        answered Dec 14 '11 at 11:12









        GillesGilles

        542k12810991616




        542k12810991616













        • (...) because the caller – I think there's something missing in this fragment.

          – Piotr Dobrogost
          Jul 20 '15 at 12:22













        • It would be ideal if $0 always starts with a - no matter how it was started. But there is at least one exception: This is not always true with bash even if it is supposed to be a login shell. Try it in your box: invoke bash --login, then $0 still reads bash.

          – Wirawan Purwanto
          Oct 16 '15 at 20:35











        • @WirawanPurwanto I'm not sure I understand your comment. Isn't that what I wrote in my last sentence?

          – Gilles
          Oct 18 '15 at 19:19











        • @Gilles: You are correct. Sorry I missed your last sentence.

          – Wirawan Purwanto
          Oct 20 '15 at 17:58



















        • (...) because the caller – I think there's something missing in this fragment.

          – Piotr Dobrogost
          Jul 20 '15 at 12:22













        • It would be ideal if $0 always starts with a - no matter how it was started. But there is at least one exception: This is not always true with bash even if it is supposed to be a login shell. Try it in your box: invoke bash --login, then $0 still reads bash.

          – Wirawan Purwanto
          Oct 16 '15 at 20:35











        • @WirawanPurwanto I'm not sure I understand your comment. Isn't that what I wrote in my last sentence?

          – Gilles
          Oct 18 '15 at 19:19











        • @Gilles: You are correct. Sorry I missed your last sentence.

          – Wirawan Purwanto
          Oct 20 '15 at 17:58

















        (...) because the caller – I think there's something missing in this fragment.

        – Piotr Dobrogost
        Jul 20 '15 at 12:22







        (...) because the caller – I think there's something missing in this fragment.

        – Piotr Dobrogost
        Jul 20 '15 at 12:22















        It would be ideal if $0 always starts with a - no matter how it was started. But there is at least one exception: This is not always true with bash even if it is supposed to be a login shell. Try it in your box: invoke bash --login, then $0 still reads bash.

        – Wirawan Purwanto
        Oct 16 '15 at 20:35





        It would be ideal if $0 always starts with a - no matter how it was started. But there is at least one exception: This is not always true with bash even if it is supposed to be a login shell. Try it in your box: invoke bash --login, then $0 still reads bash.

        – Wirawan Purwanto
        Oct 16 '15 at 20:35













        @WirawanPurwanto I'm not sure I understand your comment. Isn't that what I wrote in my last sentence?

        – Gilles
        Oct 18 '15 at 19:19





        @WirawanPurwanto I'm not sure I understand your comment. Isn't that what I wrote in my last sentence?

        – Gilles
        Oct 18 '15 at 19:19













        @Gilles: You are correct. Sorry I missed your last sentence.

        – Wirawan Purwanto
        Oct 20 '15 at 17:58





        @Gilles: You are correct. Sorry I missed your last sentence.

        – Wirawan Purwanto
        Oct 20 '15 at 17:58











        22














        fish shell



        Here's the answer for fish in case any other users stumble upon this page.



        if status --is-interactive
        # ...
        end

        if status --is-login
        # ...
        end

        echo "darn, I really wanted to have to use globs or at least a case statement"


        Fish documentation: initialization






        share|improve this answer





















        • 1





          -1 for unnecessary editorializing.

          – Nick Bastin
          Aug 20 '15 at 17:22






        • 6





          If anyone wonders at @NickBastin's comment, he had a fair point so I made an edit. The original amount of snarkiness has now been cut in half.

          – ohspite
          Aug 21 '15 at 3:56
















        22














        fish shell



        Here's the answer for fish in case any other users stumble upon this page.



        if status --is-interactive
        # ...
        end

        if status --is-login
        # ...
        end

        echo "darn, I really wanted to have to use globs or at least a case statement"


        Fish documentation: initialization






        share|improve this answer





















        • 1





          -1 for unnecessary editorializing.

          – Nick Bastin
          Aug 20 '15 at 17:22






        • 6





          If anyone wonders at @NickBastin's comment, he had a fair point so I made an edit. The original amount of snarkiness has now been cut in half.

          – ohspite
          Aug 21 '15 at 3:56














        22












        22








        22







        fish shell



        Here's the answer for fish in case any other users stumble upon this page.



        if status --is-interactive
        # ...
        end

        if status --is-login
        # ...
        end

        echo "darn, I really wanted to have to use globs or at least a case statement"


        Fish documentation: initialization






        share|improve this answer















        fish shell



        Here's the answer for fish in case any other users stumble upon this page.



        if status --is-interactive
        # ...
        end

        if status --is-login
        # ...
        end

        echo "darn, I really wanted to have to use globs or at least a case statement"


        Fish documentation: initialization







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Aug 21 '15 at 3:50

























        answered Aug 20 '15 at 6:05









        ohspiteohspite

        33626




        33626








        • 1





          -1 for unnecessary editorializing.

          – Nick Bastin
          Aug 20 '15 at 17:22






        • 6





          If anyone wonders at @NickBastin's comment, he had a fair point so I made an edit. The original amount of snarkiness has now been cut in half.

          – ohspite
          Aug 21 '15 at 3:56














        • 1





          -1 for unnecessary editorializing.

          – Nick Bastin
          Aug 20 '15 at 17:22






        • 6





          If anyone wonders at @NickBastin's comment, he had a fair point so I made an edit. The original amount of snarkiness has now been cut in half.

          – ohspite
          Aug 21 '15 at 3:56








        1




        1





        -1 for unnecessary editorializing.

        – Nick Bastin
        Aug 20 '15 at 17:22





        -1 for unnecessary editorializing.

        – Nick Bastin
        Aug 20 '15 at 17:22




        6




        6





        If anyone wonders at @NickBastin's comment, he had a fair point so I made an edit. The original amount of snarkiness has now been cut in half.

        – ohspite
        Aug 21 '15 at 3:56





        If anyone wonders at @NickBastin's comment, he had a fair point so I made an edit. The original amount of snarkiness has now been cut in half.

        – ohspite
        Aug 21 '15 at 3:56











        16














        csh / tcsh



        For csh and tcsh I have the following in my .cshrc file:



        if($?prompt) then               # Only interactive shells set $prompt
        ...
        endif


        Specifically for tcsh, the variable loginsh is set for a login shell:



        if($?loginsh) then              # A login shell..
        ...
        endif


        (tcsh also has a variable shlvl which is set to the number of nested shells, where the login shell has a value of 1.)






        share|improve this answer





















        • 2





          PS1 does not work to test for an interactive shell. It's almost always set in an interactive, but you can unset it. It's very often set in a noninteractive shell, because many systems ship with export PS in /etc/profile.

          – Gilles
          Dec 14 '11 at 11:35











        • @Gilles Thank you for the correction and edit

          – Andrew Stein
          Dec 14 '11 at 15:26
















        16














        csh / tcsh



        For csh and tcsh I have the following in my .cshrc file:



        if($?prompt) then               # Only interactive shells set $prompt
        ...
        endif


        Specifically for tcsh, the variable loginsh is set for a login shell:



        if($?loginsh) then              # A login shell..
        ...
        endif


        (tcsh also has a variable shlvl which is set to the number of nested shells, where the login shell has a value of 1.)






        share|improve this answer





















        • 2





          PS1 does not work to test for an interactive shell. It's almost always set in an interactive, but you can unset it. It's very often set in a noninteractive shell, because many systems ship with export PS in /etc/profile.

          – Gilles
          Dec 14 '11 at 11:35











        • @Gilles Thank you for the correction and edit

          – Andrew Stein
          Dec 14 '11 at 15:26














        16












        16








        16







        csh / tcsh



        For csh and tcsh I have the following in my .cshrc file:



        if($?prompt) then               # Only interactive shells set $prompt
        ...
        endif


        Specifically for tcsh, the variable loginsh is set for a login shell:



        if($?loginsh) then              # A login shell..
        ...
        endif


        (tcsh also has a variable shlvl which is set to the number of nested shells, where the login shell has a value of 1.)






        share|improve this answer















        csh / tcsh



        For csh and tcsh I have the following in my .cshrc file:



        if($?prompt) then               # Only interactive shells set $prompt
        ...
        endif


        Specifically for tcsh, the variable loginsh is set for a login shell:



        if($?loginsh) then              # A login shell..
        ...
        endif


        (tcsh also has a variable shlvl which is set to the number of nested shells, where the login shell has a value of 1.)







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Dec 14 '11 at 11:36









        Gilles

        542k12810991616




        542k12810991616










        answered Dec 13 '11 at 3:25









        Andrew SteinAndrew Stein

        26914




        26914








        • 2





          PS1 does not work to test for an interactive shell. It's almost always set in an interactive, but you can unset it. It's very often set in a noninteractive shell, because many systems ship with export PS in /etc/profile.

          – Gilles
          Dec 14 '11 at 11:35











        • @Gilles Thank you for the correction and edit

          – Andrew Stein
          Dec 14 '11 at 15:26














        • 2





          PS1 does not work to test for an interactive shell. It's almost always set in an interactive, but you can unset it. It's very often set in a noninteractive shell, because many systems ship with export PS in /etc/profile.

          – Gilles
          Dec 14 '11 at 11:35











        • @Gilles Thank you for the correction and edit

          – Andrew Stein
          Dec 14 '11 at 15:26








        2




        2





        PS1 does not work to test for an interactive shell. It's almost always set in an interactive, but you can unset it. It's very often set in a noninteractive shell, because many systems ship with export PS in /etc/profile.

        – Gilles
        Dec 14 '11 at 11:35





        PS1 does not work to test for an interactive shell. It's almost always set in an interactive, but you can unset it. It's very often set in a noninteractive shell, because many systems ship with export PS in /etc/profile.

        – Gilles
        Dec 14 '11 at 11:35













        @Gilles Thank you for the correction and edit

        – Andrew Stein
        Dec 14 '11 at 15:26





        @Gilles Thank you for the correction and edit

        – Andrew Stein
        Dec 14 '11 at 15:26











        13














        Another way is to check the result of tty



        if [ "`tty`" != "not a tty" ]; then





        share|improve this answer





















        • 10





          ... or use [ -t 0 ] to test if STDIN is a tty. You can also use 1 (STDOUT) or 2 (STDERR) depending on your needs.

          – derobert
          Dec 13 '11 at 23:17













        • @derobert - thanks for showing me something new

          – Adrian Cornish
          Dec 14 '11 at 3:12






        • 9





          This is a different test. It is possible to have a noninteractive shell whose input is a terminal (anytime you run a script in a terminal!), and it is possible (albeit rare) to have an interactive shell taking input not from a terminal.

          – Gilles
          Dec 14 '11 at 11:34











        • @Gilles if the shell was interactive, and closed leaving a child disown and alive, tty worked best to know it is not interactive anymore, while $- did not change; I am still puzzled about what is the best approach.

          – Aquarius Power
          Jul 25 '14 at 6:14






        • 5





          @AquariusPower Then what you want to test is not for an interactive shell, but whether standard input is a terminal. Use [ -t 0 ]. P.S. In my previous comment, I wrote that “there's a strong correlation” — I forgot “apart from the extremely common case of a script started with #!/bin/sh or the like”, which is non-interactive but can be connected to a terminal.

          – Gilles
          Jul 25 '14 at 7:55


















        13














        Another way is to check the result of tty



        if [ "`tty`" != "not a tty" ]; then





        share|improve this answer





















        • 10





          ... or use [ -t 0 ] to test if STDIN is a tty. You can also use 1 (STDOUT) or 2 (STDERR) depending on your needs.

          – derobert
          Dec 13 '11 at 23:17













        • @derobert - thanks for showing me something new

          – Adrian Cornish
          Dec 14 '11 at 3:12






        • 9





          This is a different test. It is possible to have a noninteractive shell whose input is a terminal (anytime you run a script in a terminal!), and it is possible (albeit rare) to have an interactive shell taking input not from a terminal.

          – Gilles
          Dec 14 '11 at 11:34











        • @Gilles if the shell was interactive, and closed leaving a child disown and alive, tty worked best to know it is not interactive anymore, while $- did not change; I am still puzzled about what is the best approach.

          – Aquarius Power
          Jul 25 '14 at 6:14






        • 5





          @AquariusPower Then what you want to test is not for an interactive shell, but whether standard input is a terminal. Use [ -t 0 ]. P.S. In my previous comment, I wrote that “there's a strong correlation” — I forgot “apart from the extremely common case of a script started with #!/bin/sh or the like”, which is non-interactive but can be connected to a terminal.

          – Gilles
          Jul 25 '14 at 7:55
















        13












        13








        13







        Another way is to check the result of tty



        if [ "`tty`" != "not a tty" ]; then





        share|improve this answer















        Another way is to check the result of tty



        if [ "`tty`" != "not a tty" ]; then






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jun 6 '12 at 14:11









        rahmu

        10.4k2070112




        10.4k2070112










        answered Dec 13 '11 at 4:30









        Adrian CornishAdrian Cornish

        1,553184




        1,553184








        • 10





          ... or use [ -t 0 ] to test if STDIN is a tty. You can also use 1 (STDOUT) or 2 (STDERR) depending on your needs.

          – derobert
          Dec 13 '11 at 23:17













        • @derobert - thanks for showing me something new

          – Adrian Cornish
          Dec 14 '11 at 3:12






        • 9





          This is a different test. It is possible to have a noninteractive shell whose input is a terminal (anytime you run a script in a terminal!), and it is possible (albeit rare) to have an interactive shell taking input not from a terminal.

          – Gilles
          Dec 14 '11 at 11:34











        • @Gilles if the shell was interactive, and closed leaving a child disown and alive, tty worked best to know it is not interactive anymore, while $- did not change; I am still puzzled about what is the best approach.

          – Aquarius Power
          Jul 25 '14 at 6:14






        • 5





          @AquariusPower Then what you want to test is not for an interactive shell, but whether standard input is a terminal. Use [ -t 0 ]. P.S. In my previous comment, I wrote that “there's a strong correlation” — I forgot “apart from the extremely common case of a script started with #!/bin/sh or the like”, which is non-interactive but can be connected to a terminal.

          – Gilles
          Jul 25 '14 at 7:55
















        • 10





          ... or use [ -t 0 ] to test if STDIN is a tty. You can also use 1 (STDOUT) or 2 (STDERR) depending on your needs.

          – derobert
          Dec 13 '11 at 23:17













        • @derobert - thanks for showing me something new

          – Adrian Cornish
          Dec 14 '11 at 3:12






        • 9





          This is a different test. It is possible to have a noninteractive shell whose input is a terminal (anytime you run a script in a terminal!), and it is possible (albeit rare) to have an interactive shell taking input not from a terminal.

          – Gilles
          Dec 14 '11 at 11:34











        • @Gilles if the shell was interactive, and closed leaving a child disown and alive, tty worked best to know it is not interactive anymore, while $- did not change; I am still puzzled about what is the best approach.

          – Aquarius Power
          Jul 25 '14 at 6:14






        • 5





          @AquariusPower Then what you want to test is not for an interactive shell, but whether standard input is a terminal. Use [ -t 0 ]. P.S. In my previous comment, I wrote that “there's a strong correlation” — I forgot “apart from the extremely common case of a script started with #!/bin/sh or the like”, which is non-interactive but can be connected to a terminal.

          – Gilles
          Jul 25 '14 at 7:55










        10




        10





        ... or use [ -t 0 ] to test if STDIN is a tty. You can also use 1 (STDOUT) or 2 (STDERR) depending on your needs.

        – derobert
        Dec 13 '11 at 23:17







        ... or use [ -t 0 ] to test if STDIN is a tty. You can also use 1 (STDOUT) or 2 (STDERR) depending on your needs.

        – derobert
        Dec 13 '11 at 23:17















        @derobert - thanks for showing me something new

        – Adrian Cornish
        Dec 14 '11 at 3:12





        @derobert - thanks for showing me something new

        – Adrian Cornish
        Dec 14 '11 at 3:12




        9




        9





        This is a different test. It is possible to have a noninteractive shell whose input is a terminal (anytime you run a script in a terminal!), and it is possible (albeit rare) to have an interactive shell taking input not from a terminal.

        – Gilles
        Dec 14 '11 at 11:34





        This is a different test. It is possible to have a noninteractive shell whose input is a terminal (anytime you run a script in a terminal!), and it is possible (albeit rare) to have an interactive shell taking input not from a terminal.

        – Gilles
        Dec 14 '11 at 11:34













        @Gilles if the shell was interactive, and closed leaving a child disown and alive, tty worked best to know it is not interactive anymore, while $- did not change; I am still puzzled about what is the best approach.

        – Aquarius Power
        Jul 25 '14 at 6:14





        @Gilles if the shell was interactive, and closed leaving a child disown and alive, tty worked best to know it is not interactive anymore, while $- did not change; I am still puzzled about what is the best approach.

        – Aquarius Power
        Jul 25 '14 at 6:14




        5




        5





        @AquariusPower Then what you want to test is not for an interactive shell, but whether standard input is a terminal. Use [ -t 0 ]. P.S. In my previous comment, I wrote that “there's a strong correlation” — I forgot “apart from the extremely common case of a script started with #!/bin/sh or the like”, which is non-interactive but can be connected to a terminal.

        – Gilles
        Jul 25 '14 at 7:55







        @AquariusPower Then what you want to test is not for an interactive shell, but whether standard input is a terminal. Use [ -t 0 ]. P.S. In my previous comment, I wrote that “there's a strong correlation” — I forgot “apart from the extremely common case of a script started with #!/bin/sh or the like”, which is non-interactive but can be connected to a terminal.

        – Gilles
        Jul 25 '14 at 7:55













        6














        UNIX/Linux has a command to check if you are on a terminal.



        if tty -s
        then
        echo Terminal
        else
        echo Not on a terminal
        fi





        share|improve this answer



















        • 1





          This works in dash also.

          – Ken Sharp
          Nov 30 '17 at 12:27
















        6














        UNIX/Linux has a command to check if you are on a terminal.



        if tty -s
        then
        echo Terminal
        else
        echo Not on a terminal
        fi





        share|improve this answer



















        • 1





          This works in dash also.

          – Ken Sharp
          Nov 30 '17 at 12:27














        6












        6








        6







        UNIX/Linux has a command to check if you are on a terminal.



        if tty -s
        then
        echo Terminal
        else
        echo Not on a terminal
        fi





        share|improve this answer













        UNIX/Linux has a command to check if you are on a terminal.



        if tty -s
        then
        echo Terminal
        else
        echo Not on a terminal
        fi






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jan 6 '16 at 13:34









        PaulPaul

        6111




        6111








        • 1





          This works in dash also.

          – Ken Sharp
          Nov 30 '17 at 12:27














        • 1





          This works in dash also.

          – Ken Sharp
          Nov 30 '17 at 12:27








        1




        1





        This works in dash also.

        – Ken Sharp
        Nov 30 '17 at 12:27





        This works in dash also.

        – Ken Sharp
        Nov 30 '17 at 12:27











        6














        You can check to see if stdin is a terminal:



        if [ -t 0 ]
        then
        echo "Hit enter"
        read ans
        fi





        share|improve this answer






























          6














          You can check to see if stdin is a terminal:



          if [ -t 0 ]
          then
          echo "Hit enter"
          read ans
          fi





          share|improve this answer




























            6












            6








            6







            You can check to see if stdin is a terminal:



            if [ -t 0 ]
            then
            echo "Hit enter"
            read ans
            fi





            share|improve this answer















            You can check to see if stdin is a terminal:



            if [ -t 0 ]
            then
            echo "Hit enter"
            read ans
            fi






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 30 mins ago









            Sam Watkins

            1056




            1056










            answered Jan 19 '16 at 1:25









            AngeloAngelo

            9431718




            9431718























                1














                Take a look at the shopt command (at least for Bash).
                That can definitely tell you if you're in a login shell. I don't know about interactive/batch.



                Reference: http://www.linuxquestions.org/questions/programming-9/how-to-check-in-a-script-whether-the-shell-is-login-or-non-login-360629/



                Look in the Bash man page for more info: http://linux.die.net/man/1/bash



                Note: I am giving you Bash, since that's what I know. Presumably other shells have similar functionality.






                share|improve this answer




























                  1














                  Take a look at the shopt command (at least for Bash).
                  That can definitely tell you if you're in a login shell. I don't know about interactive/batch.



                  Reference: http://www.linuxquestions.org/questions/programming-9/how-to-check-in-a-script-whether-the-shell-is-login-or-non-login-360629/



                  Look in the Bash man page for more info: http://linux.die.net/man/1/bash



                  Note: I am giving you Bash, since that's what I know. Presumably other shells have similar functionality.






                  share|improve this answer


























                    1












                    1








                    1







                    Take a look at the shopt command (at least for Bash).
                    That can definitely tell you if you're in a login shell. I don't know about interactive/batch.



                    Reference: http://www.linuxquestions.org/questions/programming-9/how-to-check-in-a-script-whether-the-shell-is-login-or-non-login-360629/



                    Look in the Bash man page for more info: http://linux.die.net/man/1/bash



                    Note: I am giving you Bash, since that's what I know. Presumably other shells have similar functionality.






                    share|improve this answer













                    Take a look at the shopt command (at least for Bash).
                    That can definitely tell you if you're in a login shell. I don't know about interactive/batch.



                    Reference: http://www.linuxquestions.org/questions/programming-9/how-to-check-in-a-script-whether-the-shell-is-login-or-non-login-360629/



                    Look in the Bash man page for more info: http://linux.die.net/man/1/bash



                    Note: I am giving you Bash, since that's what I know. Presumably other shells have similar functionality.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Dec 13 '11 at 1:52









                    jwdjwd

                    63847




                    63847























                        1














                        To check whether a script runs in an interactive or non-interactive shell,
                        I check in my scripts for the presence of a prompt stored in the $PS1 variable:



                        if [ -z $PS1 ] # no prompt?
                        ### if [ -v PS1 ] # On Bash 4.2+ ...
                        then
                        # non-interactive
                        ...
                        else
                        # interactive
                        ...
                        fi


                        This I learned here: https://www.tldp.org/LDP/abs/html/intandnonint.html






                        share|improve this answer




























                          1














                          To check whether a script runs in an interactive or non-interactive shell,
                          I check in my scripts for the presence of a prompt stored in the $PS1 variable:



                          if [ -z $PS1 ] # no prompt?
                          ### if [ -v PS1 ] # On Bash 4.2+ ...
                          then
                          # non-interactive
                          ...
                          else
                          # interactive
                          ...
                          fi


                          This I learned here: https://www.tldp.org/LDP/abs/html/intandnonint.html






                          share|improve this answer


























                            1












                            1








                            1







                            To check whether a script runs in an interactive or non-interactive shell,
                            I check in my scripts for the presence of a prompt stored in the $PS1 variable:



                            if [ -z $PS1 ] # no prompt?
                            ### if [ -v PS1 ] # On Bash 4.2+ ...
                            then
                            # non-interactive
                            ...
                            else
                            # interactive
                            ...
                            fi


                            This I learned here: https://www.tldp.org/LDP/abs/html/intandnonint.html






                            share|improve this answer













                            To check whether a script runs in an interactive or non-interactive shell,
                            I check in my scripts for the presence of a prompt stored in the $PS1 variable:



                            if [ -z $PS1 ] # no prompt?
                            ### if [ -v PS1 ] # On Bash 4.2+ ...
                            then
                            # non-interactive
                            ...
                            else
                            # interactive
                            ...
                            fi


                            This I learned here: https://www.tldp.org/LDP/abs/html/intandnonint.html







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Mar 15 '18 at 19:50









                            Christian HerenzChristian Herenz

                            1514




                            1514























                                0














                                i is not the correct option to look for. -i is to force an otherwise
                                non-interactive shell to become interactive. The correct auto-enabled
                                option is -s, but Bash unfortunately does not handle this correctly.



                                You need to check whether $- contains s (this is granted to be
                                auto-activated) or whether it contains i (this is not granted to
                                be auto-activated but officially only coupled to the -i command line
                                option of the shell).






                                share|improve this answer


























                                • s would be if the shell reads commands from stdin, not whether it's interactive. An interactive shell does not necessarily read commands from stdin (try zsh -i < /dev/null, though zsh seems to be the exception here). And a shell may be reading commands from stdin and not be interactive (like sh < file or echo 'echo "$1"' | sh -s foo bar).

                                  – Stéphane Chazelas
                                  Aug 18 '15 at 13:59






                                • 1





                                  What I wanted to point out is that the original Bourne Shell does not have 'i' in $-, even when it is intended to be interactive.

                                  – schily
                                  Aug 18 '15 at 14:07











                                • OK, but on U&L, "shell" tend to refer to modern shells. The Bourne shell is generally considered a relique and your own variant is not mainstream enough to expect people to know what you're talking about unless you make it explicit. The question mentioned [[...]] which implies ksh/bash/zsh. You've got a point as a history note that checking for i in $- won't work in the Bourne shell. But then checking for s won't work there reliably either. You'd want to also check for [ -t 0 ] or i; even then that'd be fooled in corner cases like echo 'exec < /dev/tty; that-check' | sh'

                                  – Stéphane Chazelas
                                  Aug 18 '15 at 14:24













                                • Solaris up to Solaris 10 come with the original Bourne Shell and even sill includes aprox. 10 bugs known to be in the shell since SVr4. So adding a hint on the Bourne Shell is not hat deviously as you might belive. zsh on the other side is not sufficient compatible, it e.g. fails when you try to run "configure" with zsh, so beware to set up /bin/sh to point to zsh. BTW: my Bourne Shell sets -i by default in case it decides to be interactive.

                                  – schily
                                  Aug 18 '15 at 14:30






                                • 1





                                  I notice POSIX doesn't seem to require $- contain i (which it seems to require s), I'll raise the question on the austin-group ML.

                                  – Stéphane Chazelas
                                  Aug 18 '15 at 15:09
















                                0














                                i is not the correct option to look for. -i is to force an otherwise
                                non-interactive shell to become interactive. The correct auto-enabled
                                option is -s, but Bash unfortunately does not handle this correctly.



                                You need to check whether $- contains s (this is granted to be
                                auto-activated) or whether it contains i (this is not granted to
                                be auto-activated but officially only coupled to the -i command line
                                option of the shell).






                                share|improve this answer


























                                • s would be if the shell reads commands from stdin, not whether it's interactive. An interactive shell does not necessarily read commands from stdin (try zsh -i < /dev/null, though zsh seems to be the exception here). And a shell may be reading commands from stdin and not be interactive (like sh < file or echo 'echo "$1"' | sh -s foo bar).

                                  – Stéphane Chazelas
                                  Aug 18 '15 at 13:59






                                • 1





                                  What I wanted to point out is that the original Bourne Shell does not have 'i' in $-, even when it is intended to be interactive.

                                  – schily
                                  Aug 18 '15 at 14:07











                                • OK, but on U&L, "shell" tend to refer to modern shells. The Bourne shell is generally considered a relique and your own variant is not mainstream enough to expect people to know what you're talking about unless you make it explicit. The question mentioned [[...]] which implies ksh/bash/zsh. You've got a point as a history note that checking for i in $- won't work in the Bourne shell. But then checking for s won't work there reliably either. You'd want to also check for [ -t 0 ] or i; even then that'd be fooled in corner cases like echo 'exec < /dev/tty; that-check' | sh'

                                  – Stéphane Chazelas
                                  Aug 18 '15 at 14:24













                                • Solaris up to Solaris 10 come with the original Bourne Shell and even sill includes aprox. 10 bugs known to be in the shell since SVr4. So adding a hint on the Bourne Shell is not hat deviously as you might belive. zsh on the other side is not sufficient compatible, it e.g. fails when you try to run "configure" with zsh, so beware to set up /bin/sh to point to zsh. BTW: my Bourne Shell sets -i by default in case it decides to be interactive.

                                  – schily
                                  Aug 18 '15 at 14:30






                                • 1





                                  I notice POSIX doesn't seem to require $- contain i (which it seems to require s), I'll raise the question on the austin-group ML.

                                  – Stéphane Chazelas
                                  Aug 18 '15 at 15:09














                                0












                                0








                                0







                                i is not the correct option to look for. -i is to force an otherwise
                                non-interactive shell to become interactive. The correct auto-enabled
                                option is -s, but Bash unfortunately does not handle this correctly.



                                You need to check whether $- contains s (this is granted to be
                                auto-activated) or whether it contains i (this is not granted to
                                be auto-activated but officially only coupled to the -i command line
                                option of the shell).






                                share|improve this answer















                                i is not the correct option to look for. -i is to force an otherwise
                                non-interactive shell to become interactive. The correct auto-enabled
                                option is -s, but Bash unfortunately does not handle this correctly.



                                You need to check whether $- contains s (this is granted to be
                                auto-activated) or whether it contains i (this is not granted to
                                be auto-activated but officially only coupled to the -i command line
                                option of the shell).







                                share|improve this answer














                                share|improve this answer



                                share|improve this answer








                                edited Dec 8 '17 at 23:35









                                Zanna

                                2,6161023




                                2,6161023










                                answered Jun 25 '15 at 9:43









                                schilyschily

                                10.8k31642




                                10.8k31642













                                • s would be if the shell reads commands from stdin, not whether it's interactive. An interactive shell does not necessarily read commands from stdin (try zsh -i < /dev/null, though zsh seems to be the exception here). And a shell may be reading commands from stdin and not be interactive (like sh < file or echo 'echo "$1"' | sh -s foo bar).

                                  – Stéphane Chazelas
                                  Aug 18 '15 at 13:59






                                • 1





                                  What I wanted to point out is that the original Bourne Shell does not have 'i' in $-, even when it is intended to be interactive.

                                  – schily
                                  Aug 18 '15 at 14:07











                                • OK, but on U&L, "shell" tend to refer to modern shells. The Bourne shell is generally considered a relique and your own variant is not mainstream enough to expect people to know what you're talking about unless you make it explicit. The question mentioned [[...]] which implies ksh/bash/zsh. You've got a point as a history note that checking for i in $- won't work in the Bourne shell. But then checking for s won't work there reliably either. You'd want to also check for [ -t 0 ] or i; even then that'd be fooled in corner cases like echo 'exec < /dev/tty; that-check' | sh'

                                  – Stéphane Chazelas
                                  Aug 18 '15 at 14:24













                                • Solaris up to Solaris 10 come with the original Bourne Shell and even sill includes aprox. 10 bugs known to be in the shell since SVr4. So adding a hint on the Bourne Shell is not hat deviously as you might belive. zsh on the other side is not sufficient compatible, it e.g. fails when you try to run "configure" with zsh, so beware to set up /bin/sh to point to zsh. BTW: my Bourne Shell sets -i by default in case it decides to be interactive.

                                  – schily
                                  Aug 18 '15 at 14:30






                                • 1





                                  I notice POSIX doesn't seem to require $- contain i (which it seems to require s), I'll raise the question on the austin-group ML.

                                  – Stéphane Chazelas
                                  Aug 18 '15 at 15:09



















                                • s would be if the shell reads commands from stdin, not whether it's interactive. An interactive shell does not necessarily read commands from stdin (try zsh -i < /dev/null, though zsh seems to be the exception here). And a shell may be reading commands from stdin and not be interactive (like sh < file or echo 'echo "$1"' | sh -s foo bar).

                                  – Stéphane Chazelas
                                  Aug 18 '15 at 13:59






                                • 1





                                  What I wanted to point out is that the original Bourne Shell does not have 'i' in $-, even when it is intended to be interactive.

                                  – schily
                                  Aug 18 '15 at 14:07











                                • OK, but on U&L, "shell" tend to refer to modern shells. The Bourne shell is generally considered a relique and your own variant is not mainstream enough to expect people to know what you're talking about unless you make it explicit. The question mentioned [[...]] which implies ksh/bash/zsh. You've got a point as a history note that checking for i in $- won't work in the Bourne shell. But then checking for s won't work there reliably either. You'd want to also check for [ -t 0 ] or i; even then that'd be fooled in corner cases like echo 'exec < /dev/tty; that-check' | sh'

                                  – Stéphane Chazelas
                                  Aug 18 '15 at 14:24













                                • Solaris up to Solaris 10 come with the original Bourne Shell and even sill includes aprox. 10 bugs known to be in the shell since SVr4. So adding a hint on the Bourne Shell is not hat deviously as you might belive. zsh on the other side is not sufficient compatible, it e.g. fails when you try to run "configure" with zsh, so beware to set up /bin/sh to point to zsh. BTW: my Bourne Shell sets -i by default in case it decides to be interactive.

                                  – schily
                                  Aug 18 '15 at 14:30






                                • 1





                                  I notice POSIX doesn't seem to require $- contain i (which it seems to require s), I'll raise the question on the austin-group ML.

                                  – Stéphane Chazelas
                                  Aug 18 '15 at 15:09

















                                s would be if the shell reads commands from stdin, not whether it's interactive. An interactive shell does not necessarily read commands from stdin (try zsh -i < /dev/null, though zsh seems to be the exception here). And a shell may be reading commands from stdin and not be interactive (like sh < file or echo 'echo "$1"' | sh -s foo bar).

                                – Stéphane Chazelas
                                Aug 18 '15 at 13:59





                                s would be if the shell reads commands from stdin, not whether it's interactive. An interactive shell does not necessarily read commands from stdin (try zsh -i < /dev/null, though zsh seems to be the exception here). And a shell may be reading commands from stdin and not be interactive (like sh < file or echo 'echo "$1"' | sh -s foo bar).

                                – Stéphane Chazelas
                                Aug 18 '15 at 13:59




                                1




                                1





                                What I wanted to point out is that the original Bourne Shell does not have 'i' in $-, even when it is intended to be interactive.

                                – schily
                                Aug 18 '15 at 14:07





                                What I wanted to point out is that the original Bourne Shell does not have 'i' in $-, even when it is intended to be interactive.

                                – schily
                                Aug 18 '15 at 14:07













                                OK, but on U&L, "shell" tend to refer to modern shells. The Bourne shell is generally considered a relique and your own variant is not mainstream enough to expect people to know what you're talking about unless you make it explicit. The question mentioned [[...]] which implies ksh/bash/zsh. You've got a point as a history note that checking for i in $- won't work in the Bourne shell. But then checking for s won't work there reliably either. You'd want to also check for [ -t 0 ] or i; even then that'd be fooled in corner cases like echo 'exec < /dev/tty; that-check' | sh'

                                – Stéphane Chazelas
                                Aug 18 '15 at 14:24







                                OK, but on U&L, "shell" tend to refer to modern shells. The Bourne shell is generally considered a relique and your own variant is not mainstream enough to expect people to know what you're talking about unless you make it explicit. The question mentioned [[...]] which implies ksh/bash/zsh. You've got a point as a history note that checking for i in $- won't work in the Bourne shell. But then checking for s won't work there reliably either. You'd want to also check for [ -t 0 ] or i; even then that'd be fooled in corner cases like echo 'exec < /dev/tty; that-check' | sh'

                                – Stéphane Chazelas
                                Aug 18 '15 at 14:24















                                Solaris up to Solaris 10 come with the original Bourne Shell and even sill includes aprox. 10 bugs known to be in the shell since SVr4. So adding a hint on the Bourne Shell is not hat deviously as you might belive. zsh on the other side is not sufficient compatible, it e.g. fails when you try to run "configure" with zsh, so beware to set up /bin/sh to point to zsh. BTW: my Bourne Shell sets -i by default in case it decides to be interactive.

                                – schily
                                Aug 18 '15 at 14:30





                                Solaris up to Solaris 10 come with the original Bourne Shell and even sill includes aprox. 10 bugs known to be in the shell since SVr4. So adding a hint on the Bourne Shell is not hat deviously as you might belive. zsh on the other side is not sufficient compatible, it e.g. fails when you try to run "configure" with zsh, so beware to set up /bin/sh to point to zsh. BTW: my Bourne Shell sets -i by default in case it decides to be interactive.

                                – schily
                                Aug 18 '15 at 14:30




                                1




                                1





                                I notice POSIX doesn't seem to require $- contain i (which it seems to require s), I'll raise the question on the austin-group ML.

                                – Stéphane Chazelas
                                Aug 18 '15 at 15:09





                                I notice POSIX doesn't seem to require $- contain i (which it seems to require s), I'll raise the question on the austin-group ML.

                                – Stéphane Chazelas
                                Aug 18 '15 at 15:09


















                                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%2f26676%2fhow-to-check-if-a-shell-is-login-interactive-batch%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

                                CARDNET

                                Boot-repair Failure: Unable to locate package grub-common:i386

                                濃尾地震