Назначения подобны командам со статусом выхода, за исключением случаев подстановки команд?

Есть несколько комментариев, которые не получили подходящего ответа. Вот некоторые моменты:

  • xterm не принимает "произвольные двоичные данные". Он принимает (в зависимости от локали) UTF-8 или ISO-8859-1. Последняя следует ICCM, первая является расширением XFree86. В любой кодировке xterm может интерпретировать эти символы, чтобы (попытаться) предоставить данные из выбора. При вставке текста UTF-8 из выделения в кодировку ISO-8859-1, он будет аппроксимировать наиболее часто используемые символы (включая построчное начертание).

  • выбор (и вставка) зависят как от источника (где делается выбор), так и от цели (куда вставляется текст). Оба должны договориться о формате данных для выделения/вставки. xterm предоставляет и принимает несколько форматов (см. button.c в sources). Konsole и gnome-terminal используют меньше форматов.

  • Konsole, например, делает выбор X11 как бы в последнюю очередь. Она использует метод QClipboard::Selection . Комментарии на странице Qt в разделе Заметки для пользователей X11 - интересное чтение в этом отношении. Но прочитайте код и увидите, что он только поддерживает COMPOUND_TEXT:

    if (*format == 8 && *type == ATOM(COMPOUND_TEXT)) { // преобразование COMPOUND_TEXT)
     // преобразуем COMPOUND_TEXT в многобайтовую строку
     XTextProperty textprop;
     textprop.encoding = *type;
     textprop.format = *format;
     textprop.nitems = buffer_offset;
     textprop.value = (unsigned char *) buffer->data();
    
     char **list_ret = 0;
     int count;
     if (XmbTextPropertyToTextList(display, &textprop, &list_ret,
     &count) == Success && count && list_ret) {
     offset = buffer_offset = strlen(list_ret[0]);
     buffer->resize(offset);
     memcpy(buffer->data(), list_ret[0], offset);
     }
     if (list_ret) XFreeStringList(list_ret);
    }
    
  • Аналогично, VTE GNOME использует gtk_clipboard_get_for_display, в целом следуя примеру Qt.

  • IBM 850 является 8-битной кодировкой (как ISO-8859-1), и не может представлять символ замены UTF-8. Поэтому ваш терминал использует ? (символ по умолчанию).

Дальнейшее чтение:

10
29.01.2017, 22:28
2 ответа

Статус выхода для назначений странный .Наиболее очевидный способ неудачи присваивания - если целевая переменная помечена только для чтения .

$ err(){ echo error ; return ${1:-1} ; }
$ PS1='$? $ '
0 $ err 42
error
42 $ A=$(err 12)
12 $ if A=$(err 9) ; then echo wrong ; else E=$? ; echo "E=$E ?=$?" ; fi
E=9 ?=0
0 $ readonly A
0 $ if A=$(err 10) ; then echo wrong ; else E=$? ; echo "E=$E ?=$?" ; fi
A: is read only
1 $

Обратите внимание, что ни истинный, ни ложный пути оператора if не использовались, сбой присваивания остановил выполнение всего оператора. bash в режиме POSIX, а ksh93 и zsh прервут сценарий, если присвоение не удалось.

Процитируем стандарт POSIX для этого :

Команда без имени команды, но та, которая включает подстановку команды, имеет статус выхода последней подстановки команды, выполненной оболочкой.

Это именно та часть грамматики оболочки, которая задействована в

 foo=$(err 42)

, которая происходит от simple_command (simple_command → cmd_prefix → ASSIGNMENT_WORD). Таким образом, если присвоение выполнено успешно, то статус выхода равен нулю, если не была задействована подстановка команд, и в этом случае статус выхода является статусом последнего. Если присваивание не выполняется, то статус выхода не равен нулю, но вы не сможете его поймать.

10
27.01.2020, 20:01

Вы говорите:

... похоже, что само назначение считается командой... с нулевым значением выхода, но которая применяется перед правой частью присваивания (например, вызов подстановки команды...)

Это не такой уж плохой способ взглянуть на это.  Но это небольшое упрощение.  Общий статус возврата из

A=$(cmd1)  B=$(cmd2)  C=$(cmd3)  D=$(cmd4)  E=mc2
- это статус выхода из cmd4.  Назначение E=, которое происходит после назначения D=. не устанавливает общий статус выхода в 0.

Кроме того, как указывает icarus , переменные могут быть установлены как readonly.  Рассмотрим следующий вариант примера icarus:

$ err() { echo "stdout $*"; echo "stderr $*" >&2; return ${1:-1}; }
$ readonly A
$ Z=$(err 41 zebra) A=$(err 42 antelope) B=$(err 43 badger)
stderr 41 zebra
stderr 42 antelope
bash: A: readonly variable
$ echo $?
1
$ printf "%s = %s\n" Z "$Z" A "$A" B "$B"
Z = stdout 41 zebra
A =
B =
$

Несмотря на то, что A является readonly, bash выполняет подстановку команды справа от A= -... и then прерывает команду, потому что A доступен только для чтения.  Это еще больше противоречит вашей интерпретации что значение выхода из присваивания применяется перед правой частью присваивания.

4
27.01.2020, 20:01

Теги

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