从https://unix.stackexchange.com/a/276611/674:
当 bash 使用 -c 运行时,它被视为非交互式 shell,并且不会读取 ~/.bashrc,除非指定了 -i。
非交互式 shell 是如何定义的?
非交互式 shell 是否定义为无法接受来自 stdin 的输入的 shell?例如
bash -c cat
可以接受来自 stdin 的输入。非交互式 shell 可以输出到 stdout 吗?例如,
bash -c date
可以写入标准输出。
bash -c
(没有附加选项)是否-i
总是创建非交互式 shell?
答案1
我做了一些调查。根据bash的源码。
长话短说
非交互式 shell 是如何定义的?
- 缺少命令历史记录
- 不支持工作
- 没有行编辑功能
- 错误获取行号
- 没有提示
- 第一次错误后停止执行
bash -c(没有附加 -i 选项)是否总是创建非交互式 shell?
是的
更长的版本。
当 bash 接收到选项时调用该函数-c
。
no_line_editing = 1
意味着您无法使用退格键编辑命令。
bash_history_reinit (0);
禁用历史记录和命令自动完成。
static void
init_noninteractive ()
{
#if defined (HISTORY)
bash_history_reinit (0);
#endif /* HISTORY */
interactive_shell = startup_state = interactive = 0;
expand_aliases = posixly_correct; /* XXX - was 0 not posixly_correct */
no_line_editing = 1;
#if defined (JOB_CONTROL)
/* Even if the shell is not interactive, enable job control if the -i or
-m option is supplied at startup. */
set_job_control (forced_interactive||jobs_m_flag);
#endif /* JOB_CONTROL */
}
默认情况下,作业控制处于禁用状态,除非您强制使用-m
/* We can only have job control if we are interactive unless we
force it. */
if (interactive == 0 && force == 0)
{
job_control = 0;
original_pgrp = NO_PID;
shell_tty = fileno (stderr);
}
语法错误消息包含行号。
/* Report a syntax error with line numbers, etc.
Call here for recoverable errors. If you have a message to print,
then place it in MESSAGE, otherwise pass NULL and this will figure
out an appropriate message for you. */
static void
report_syntax_error (message)
char *message;
{
...
if (interactive == 0)
print_offending_line ();
...
}
简单测试
root@test:~# ;;
-bash: syntax error near unexpected token `;;'
root@test:~# bash -c ';;'
bash: -c: line 0: syntax error near unexpected token `;;'
bash: -c: line 0: `;;'
命令执行后不打印提示。
/* Issue a prompt, or prepare to issue a prompt when the next character
is read. */
static void
prompt_again ()
{
char *temp_prompt;
if (interactive == 0 || expanding_alias ()) /* XXX */
return;
命令执行在第一次错误后停止。
/* Parse error, maybe discard rest of stream if not interactive. */
if (interactive == 0)
EOF_Reached = EOF;
答案2
在 shell 会话中,有许多选项,例如:
- 别名是否已扩展
- 某人/某物正在 STDIN 上打字
- 完成系统是否已加载
- 如果命令存储在历史文件中
- 哪些文件是在 shell 启动时获取的
交互式 shell 是具有其中一些特征的 shell。但是,您可以根据自己的喜好打开或关闭这些选项。可以将这个词视为interactive shell
我们通常理解的 shell 交互所需的行为的集合。
当您使用 启动 shell 时-i
,它会变得有点混乱,因为它通常表明您正在扰乱系统。其中一些 shell 选项可能具有不同于人们通常理解的交互式 shell 的其他值。
因此,具体而言,您的示例bash -c cat
将不会启用完成功能,也不会在历史记录中存储任何内容。我不想这样称呼interactive
,但如果您愿意的话,您可以自由地这样做。
答案3
交互式 shell 定义为从 stdin 读取命令的 shell。
通过使用选项“定义”为交互式的非交互式 shell 是否-i
读取$ENV
文件 ( ~/.*rc
) 是未定义的。