'Login'和'Interactive'bash shell有什么区别(来自其他站点:serverfault.com)
2.1:外壳类型:交互外壳和登录外壳(从Z-Shell用户指南开始)
我的问题是,如何使用命令/条件进行测试如果我是在交互式,登录名或批处理shell中?
我正在寻找命令或条件(返回
true
或false
),并且也可以在if语句上放置。例如:if [[ condition ]]
echo "This is a login shell"
fi
#1 楼
我假设使用bash
外壳或类似的外壳,因为标签中没有列出外壳。要检查您是否在交互式外壳中: />
要检查您是否在登录外壳中:
[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'
通过“批处理”,我假设您的意思是“非交互式”,因此检查交互式外壳就足够了。
评论
对于zsh用户,可以使用以下命令检查登录shell:if [[-o login]] ...
–chb
2013年6月27日5:05
如果您想知道“用户”相对于“ cron”是否运行了程序。 [[TERM ==“ dumb”]] && echo“在cron中运行。
– Erik Aronesty
2013年12月3日17:49
@ErikAronesty并非所有的哑终端都是cron会话。
–克里斯唐(Chris Down)
13年12月4日在22:11
同样对于zsh用户,要检查交互式会话:[[-o交互式]]
–弗兰克·特贝克(Frank Terbeck)
15年8月10日在16:50
“我假设是bash shell或类似的东西,因为标签中没有列出shell。” –此声明的逻辑确实很漂亮! :)
–MichaëlLe Barbier
15年12月14日在8:44
#2 楼
在任何Bourne风格的外壳程序中,i
选项都表明该外壳程序是否是交互式的:case $- in
*i*) echo "This shell is interactive";;
*) echo "This is a script";;
esac
没有可移植且完全可靠的方法来测试登录外壳程序。 Ksh和zsh将
l
添加到$-
中。 Bash设置了login_shell
选项,您可以使用shopt -q login_shell
进行查询。可移植地,测试-
是否以-
开头:外壳程序通常知道它们是登录外壳程序,因为调用者在参数0(通常是可执行文件的名称或路径)上添加了ash -l
前缀。这无法检测到特定于Shell的调用登录Shell的方式(例如q4312079q)。评论
(...),因为呼叫者–我认为此片段中缺少某些内容。
–彼得·多布罗格斯特(Piotr Dobrogost)
15年7月20日在12:22
如果$ 0始终以-开头,则不管它如何开始,这都是理想的。但是至少有一个例外:对于bash,这并不总是正确的,即使它应该是登录shell。在您的框中尝试一下:调用bash --login,然后$ 0仍读取bash。
– irawan Purwanto
15-10-16在20:35
@WirawanPurwanto我不确定我是否理解您的评论。那不是我在最后一句话中写的吗?
–吉尔斯'所以-不再是邪恶的'
15年10月18日在19:19
@吉尔斯:你是对的。对不起,我错过了你的最后一句话。
– irawan Purwanto
15年10月20日在17:58
#3 楼
鱼壳这是
fish
的答案,以防其他用户偶然发现此页面。 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"
鱼类文档:初始化
评论
-1用于不必要的编辑。
–尼克·巴斯汀(Nick Bastin)
15年8月20日在17:22
如果有人对@NickBastin的评论感到惊讶,他的观点很合理,所以我进行了编辑。原来的贪睡已经减少了一半。
–哎呀
2015年8月21日,下午3:56
#4 楼
csh / tcsh对于
csh
和tcsh
我在.cshrc
文件中具有以下内容:if($?prompt) then # Only interactive shells set $prompt
...
endif
专门针对
tcsh
,设置了变量loginsh
对于登录Shell:if($?loginsh) then # A login shell..
...
endif
(
tcsh
还有一个变量shlvl
,该变量设置为嵌套shell的数量,其中登录shell的值为1。) 评论
PS1无法测试交互式外壳。它几乎总是以交互方式设置,但是您可以取消设置。通常将其设置在非交互式外壳中,因为许多系统在/ etc / profile中附带了导出PS。
–吉尔斯'所以-不再是邪恶的'
2011-12-14 11:35
@Gilles感谢您的纠正和编辑
–安德鲁·斯坦(Andrew Stein)
2011-12-14 15:26
这就是Gold:tcsh也有一个变量shlvl,它设置为嵌套shell的数量,其中登录shell的值为1。
– Israr
19-10-28在23:01
#5 楼
另一种方法是检查tty
的结果if [ "`tty`" != "not a tty" ]; then
评论
...或使用[-t 0]测试STDIN是否为tty。您还可以根据需要使用1(STDOUT)或2(STDERR)。
–德罗伯特
2011-12-13 23:17
@derobert-感谢您向我展示一些新东西
– Adrian Cornish
2011年12月14日,下午3:12
这是一个不同的测试。可能有一个非交互式外壳,其输入是终端(无论何时在终端中运行脚本!),也有可能(尽管很少)有一个交互式外壳而不是从终端接收输入。
–吉尔斯'所以-不再是邪恶的'
2011-12-14 11:34
@Gilles,如果外壳是交互式的,并且关闭了,让一个孩子消失了,还活着,那么tty最好知道它不再是交互式的,而$-并没有改变;我仍然对最佳方法感到困惑。
–水瓶座力量
2014年7月25日下午6:14
@AquariusPower然后,您要测试的不是交互式外壳,而是标准输入是否为终端。使用[-t 0]。附言在我之前的评论中,我写道“存在很强的相关性”-我忘记了“除了以#!/ bin / sh之类的脚本开头的极其常见的情况”,该脚本是非交互式的,但可以连接到一个终端。
–吉尔斯'所以-不再是邪恶的'
2014年7月25日7:55
#6 楼
UNIX / Linux有一个命令来检查您是否在终端上。if tty -s
then
echo Terminal
else
echo Not on a terminal
fi
评论
这在破折号中也有效。
–肯·夏普
17年11月30日在12:27
#7 楼
您可以检查stdin是否为终端:if [ -t 0 ]
then
echo "Hit enter"
read ans
fi
#8 楼
适用于Zsh # Checking Interactive v.s. Non-Interactive
[[ -o interactive ]] && echo "Interactive" || echo "Non-Interactive"
#
# Checking Login v.s. Non-Login
[[ -o login ]] && echo "Login" || echo "Non-Login"
参考:2.1.1:什么是登录shell?简单测试
#9 楼
i
不是要查找的正确选项。 -i
将强制否则为非交互式的shell进行交互。正确的自动启用的选项是
-s
,但遗憾的是Bash无法正确处理。您需要检查
$-
是否包含s
(这被授予为auto-已激活)或它是否包含
i
(这不是授予自动激活的权限,而是正式地仅与
-i
命令行评论
如果外壳程序从stdin读取命令,则不是,而不是它是否是交互式的。交互式外壳程序不一定从stdin读取命令(尝试zsh -i dev / null,尽管zsh似乎是例外)。 Shell可能正在从stdin读取命令,并且不是交互式的(例如sh <文件或echo'echo“ $ 1”'| sh -s foo bar)。
–StéphaneChazelas
15年8月18日在13:59
我想指出的是,即使是旨在进行交互的,原始的Bourne Shell也没有在$-中包含“ i”。
–schily
15年8月18日在14:07
可以,但是在U&L上,“外壳”往往是指现代外壳。 Bourne shell通常被认为是一种传统,并且您自己的变体还不够主流,无法期望人们知道您在说什么,除非您明确指出。提到的问题[[]]暗示ksh / bash / zsh。作为历史记录,您有一点要说,在Bourne shell中检查$-中的i无效。但是然后检查s也不可靠。您还需要检查[-t 0]或i;即使那样,在回声'exec dev / tty;检查” |嘘
–StéphaneChazelas
2015年8月18日14:24
最初的Bourne Shell附带Solaris直至Solaris 10,甚至包括门槛在内的窗台。自SVr4以来,shell中已知存在10个错误。因此,在Bourne Shell上添加提示并非如您所愿。另一端的zsh兼容性不足,例如当您尝试使用zsh运行“配置”时失败,因此请注意将/ bin / sh设置为指向zsh。顺便说一句:我的Bourne Shell在默认情况下设置-i以防万一,它决定是交互式的。
–schily
15年8月18日在14:30
我注意到POSIX似乎不需要$-包含i(它似乎需要s),我将在奥斯汀集团ML上提出这个问题。
–StéphaneChazelas
15年8月18日在15:09
#10 楼
要检查脚本是在交互式外壳程序中还是在非交互式外壳程序中运行,我在脚本中检查是否存在存储在
$PS1
变量中的提示:if [ -z $PS1 ] # no prompt?
### if [ -v PS1 ] # On Bash 4.2+ ...
then
# non-interactive
...
else
# interactive
...
fi
这是我在这里学到的:https://www.tldp.org/LDP/abs/html/intandnonint.html
#11 楼
奇怪的是,在MacOS中从桌面启动的脚本与手工启动的脚本具有相同的环境。 (他们将标准输入作为电传打字机tty,未设置login_shell
商店,将"$-"
设置为ehxB
)如果我将脚本带到桌面的首选方法是创建从
~/Desktop
到脚本的符号链接,我可以仅通过检查"q4312079q"
是否为绝对路径(即以斜杠开头)来猜测它是通过单击启动的。
评论
还有另一个问题:STDIN和/或STDOUT是否连接到tty(终端)或管道(文件或进程)?这是一个相关但截然不同的测试,如以下一些评论所述。