来自https://unix.stackexchange.com/a/276611/674:
当 bash 使用 -c 运行时,它被认为是一个非交互式 shell,它不会读取 ~/.bashrc,除非指定了 -i。
非交互式 shell 是如何定义的?
非交互式 shell 是否定义为不能接受来自 stdin 的输入的 shell?例如bash -c cat
可以接受来自标准输入的输入。
非交互式 shell 可以输出到标准输出吗?例如,bash -c date
可以写入标准输出。
是否bash -c
(没有附加-i
选项)总是创建一个非交互式 shell?
我做了一些调查。根据bash的源代码。
TL; 博士
非交互式 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 */
}
Run Code Online (Sandbox Code Playgroud)
默认情况下禁用作业控制,除非您强制使用它 -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);
}
Run Code Online (Sandbox Code Playgroud)
语法错误消息包含行号。
/* 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 ();
...
}
Run Code Online (Sandbox Code Playgroud)
简单测试
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: `;;'
Run Code Online (Sandbox Code Playgroud)
命令执行后不打印提示。
/* 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;
Run Code Online (Sandbox Code Playgroud)
第一个错误后命令执行停止。
/* Parse error, maybe discard rest of stream if not interactive. */
if (interactive == 0)
EOF_Reached = EOF;
Run Code Online (Sandbox Code Playgroud)