How to check if a shell is login/interactive/batch
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
add a comment |
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
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
add a comment |
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
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
shell
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
add a comment |
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
add a comment |
10 Answers
10
active
oldest
votes
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.
12
Forzsh
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
|
show 7 more comments
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
).
(...) 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: invokebash --login
, then$0
still readsbash
.
– 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
add a comment |
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
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
add a comment |
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.)
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 withexport 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
add a comment |
Another way is to check the result of tty
if [ "`tty`" != "not a tty" ]; then
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 childdisown
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
|
show 4 more comments
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
1
This works indash
also.
– Ken Sharp
Nov 30 '17 at 12:27
add a comment |
You can check to see if stdin is a terminal:
if [ -t 0 ]
then
echo "Hit enter"
read ans
fi
add a comment |
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.
add a comment |
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
add a comment |
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).
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 (tryzsh -i < /dev/null
, though zsh seems to be the exception here). And a shell may be reading commands from stdin and not be interactive (likesh < file
orecho '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 fori
in$-
won't work in the Bourne shell. But then checking fors
won't work there reliably either. You'd want to also check for[ -t 0 ]
ori
; even then that'd be fooled in corner cases likeecho '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
|
show 7 more comments
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
12
Forzsh
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
|
show 7 more comments
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.
12
Forzsh
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
|
show 7 more comments
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.
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.
answered Dec 13 '11 at 23:19
Chris DownChris Down
81.1k15189203
81.1k15189203
12
Forzsh
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
|
show 7 more comments
12
Forzsh
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
|
show 7 more comments
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
).
(...) 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: invokebash --login
, then$0
still readsbash
.
– 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
add a comment |
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
).
(...) 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: invokebash --login
, then$0
still readsbash
.
– 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
add a comment |
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
).
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
).
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: invokebash --login
, then$0
still readsbash
.
– 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
add a comment |
(...) 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: invokebash --login
, then$0
still readsbash
.
– 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
add a comment |
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
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
add a comment |
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
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
add a comment |
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
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
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
add a comment |
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
add a comment |
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.)
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 withexport 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
add a comment |
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.)
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 withexport 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
add a comment |
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.)
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.)
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 withexport 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
add a comment |
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 withexport 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
add a comment |
Another way is to check the result of tty
if [ "`tty`" != "not a tty" ]; then
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 childdisown
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
|
show 4 more comments
Another way is to check the result of tty
if [ "`tty`" != "not a tty" ]; then
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 childdisown
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
|
show 4 more comments
Another way is to check the result of tty
if [ "`tty`" != "not a tty" ]; then
Another way is to check the result of tty
if [ "`tty`" != "not a tty" ]; then
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 childdisown
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
|
show 4 more comments
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 childdisown
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
|
show 4 more comments
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
1
This works indash
also.
– Ken Sharp
Nov 30 '17 at 12:27
add a comment |
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
1
This works indash
also.
– Ken Sharp
Nov 30 '17 at 12:27
add a comment |
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
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
answered Jan 6 '16 at 13:34
PaulPaul
6111
6111
1
This works indash
also.
– Ken Sharp
Nov 30 '17 at 12:27
add a comment |
1
This works indash
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
add a comment |
You can check to see if stdin is a terminal:
if [ -t 0 ]
then
echo "Hit enter"
read ans
fi
add a comment |
You can check to see if stdin is a terminal:
if [ -t 0 ]
then
echo "Hit enter"
read ans
fi
add a comment |
You can check to see if stdin is a terminal:
if [ -t 0 ]
then
echo "Hit enter"
read ans
fi
You can check to see if stdin is a terminal:
if [ -t 0 ]
then
echo "Hit enter"
read ans
fi
edited 30 mins ago
Sam Watkins
1056
1056
answered Jan 19 '16 at 1:25
AngeloAngelo
9431718
9431718
add a comment |
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered Dec 13 '11 at 1:52
jwdjwd
63847
63847
add a comment |
add a comment |
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
add a comment |
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
add a comment |
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
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
answered Mar 15 '18 at 19:50
Christian HerenzChristian Herenz
1514
1514
add a comment |
add a comment |
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).
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 (tryzsh -i < /dev/null
, though zsh seems to be the exception here). And a shell may be reading commands from stdin and not be interactive (likesh < file
orecho '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 fori
in$-
won't work in the Bourne shell. But then checking fors
won't work there reliably either. You'd want to also check for[ -t 0 ]
ori
; even then that'd be fooled in corner cases likeecho '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
|
show 7 more comments
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).
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 (tryzsh -i < /dev/null
, though zsh seems to be the exception here). And a shell may be reading commands from stdin and not be interactive (likesh < file
orecho '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 fori
in$-
won't work in the Bourne shell. But then checking fors
won't work there reliably either. You'd want to also check for[ -t 0 ]
ori
; even then that'd be fooled in corner cases likeecho '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
|
show 7 more comments
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).
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).
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 (tryzsh -i < /dev/null
, though zsh seems to be the exception here). And a shell may be reading commands from stdin and not be interactive (likesh < file
orecho '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 fori
in$-
won't work in the Bourne shell. But then checking fors
won't work there reliably either. You'd want to also check for[ -t 0 ]
ori
; even then that'd be fooled in corner cases likeecho '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
|
show 7 more comments
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 (tryzsh -i < /dev/null
, though zsh seems to be the exception here). And a shell may be reading commands from stdin and not be interactive (likesh < file
orecho '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 fori
in$-
won't work in the Bourne shell. But then checking fors
won't work there reliably either. You'd want to also check for[ -t 0 ]
ori
; even then that'd be fooled in corner cases likeecho '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
|
show 7 more comments
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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