bash -c и неинтерактивная оболочка [дубликат]

Вы можете очистить его, переустановив параметры на: "пустая строка", за которой следуют "параметры, начиная со 2-го":

$ set -- 1 2 3 4
$ printf -- "->%s<-\n" "$@"
->1<-
->2<-
->3<-
->4<-
$ set -- "" "${@:2}"
$ printf -- "->%s<-\n" "$@"
-><-
->2<-
->3<-
->4<-
0
13.04.2017, 15:37
3 ответа

В сеансе оболочки есть несколько опций, например:

  • раскрываются псевдонимы;
  • кто-то / что-то набирает на STDIN
  • загружается система завершения
  • , если команды хранятся в файле истории
  • , файлы из которых исходят из файлов в начале оболочки

Интерактивная оболочка - это оболочка, которая имеет некоторые из этих характеристик . Однако вы можете включить или выключить эти параметры по своему вкусу. Думайте о слове интерактивная оболочка как о наборе поведений, которые, как мы обычно понимаем, необходимы для того, чтобы оболочка была интерактивной.

Когда вы запускаете оболочку с помощью -i , она становится немного запутанной, поскольку обычно указывает на то, что вы возитесь с системой. Может случиться так, что некоторые из этих параметров оболочки будут иметь другое значение, отличное от того, что обычно понимается как интерактивная оболочка.

Конкретно, в вашем примере bash -c cat не будет включено завершение, и он ничего не сохранит в истории. Я бы не стал называть это интерактивным , но вы можете сделать это, если захотите.

3
28.01.2020, 02:13

Интерактивная оболочка определяется как оболочка, считывающая команды из стандартного ввода.

Считывает ли неинтерактивная оболочка, которая «определена» как интерактивная с помощью параметра -i , файл $ ENV ( ~ /.* rc ) не определено.

1
28.01.2020, 02:13

Я провел некоторые исследования. Согласно исходному коду bash.

TL;DR

Как определяется неинтерактивная оболочка?

  • отсутствие истории команд
  • задания не поддерживаются
  • нет возможности редактирования строк
  • ошибки получают номер строки
  • нет подсказки
  • выполнение останавливается после первой ошибки

Всегда ли bash -c (без дополнительной опции -i) создает неинтерактивную оболочку? неинтерактивную оболочку?

Да

Более длинная версия.

Эта функция вызывается, когда bash получает опцию -c.

no_line_editing = 1 означает, что вы не можете редактировать свои команды, используя backspace.

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;
6
28.01.2020, 02:13

Теги

Похожие вопросы