4

Насколько я понимаю, следующее должно отправить ' test ' на стандартную ошибку в tcsh:

echo test >&2

Однако вместо этого он записывает ' test ' в файл с именем 2 , и когда я просматриваю свою историю, я обнаруживаю, что фактически выполненное

echo test > & 2

Я не уверен, какой слой вставляет эти пробелы, но могу ли я как-нибудь это остановить? Если нет, то я думаю, что я всегда мог бы использовать > /dev/stderr .

4 ответа4

5

По поводу csh:http://www.faqs.org/faqs/unix-faq/shell/csh-whynot/:

Кроме того, вы не можете направлять сообщения об ошибках в сценариях csh из stderr, как это считается правильным. В оболочке Bourne вы можете сказать:

echo "$0: cannot find $file" 1>&2

но в csh вы не можете перенаправить stdout из stderr, так что в итоге вы делаете что-то глупое:

sh -c 'echo "$0: cannot find $file" 1>&2'

Я сделал несколько быстрых попыток с tcsh , и, как и предполагалось, это также верно для этого (предполагается, что tcsh полностью совместим с csh).


Чтобы ответить на ваш сформулированный вопрос: не имело бы значения, если бы вы могли заставить tcsh не "вставлять пробелы", так как он все равно не будет интерпретировать эту последовательность по назначению.

5

РЕДАКТИРОВАТЬ:

Я не видел, что это был тсч. Подробности смотрите в разделе «Ввод / вывод» man tsch :

Диагностический выход может быть направлен через трубу со стандартным выходом. Просто используйте форму | &, а не просто |.

В настоящее время оболочка не может перенаправить диагностический вывод без перенаправления стандартного вывода, но (команда> файл-вывода)> & файл-ошибки часто является приемлемым обходным решением. Выходной файл или файл ошибок может быть /dev /tty для отправки на терминал.

3

Решение Даниэля Андерссона великолепно и будет работать хорошо, если команду, которую вы хотите запустить, можно запустить из sh (и, следовательно, подоболочки, которая не сможет изменить каталог или изменить среду вашей текущей оболочки). Если вы хотите преобразовать stdout в stderr, но сохранить выполнение команды в текущей оболочке, вы можете использовать bash только для перенаправления stdout-to-stderr, например так:

echo "Сообщение об ошибке" | bash -c "кот - 1> & 2"

1

Я провел несколько экспериментов с указанием /dev /stderr в сценарии tcsh. Я хотел, чтобы пользователь скрипта мог (также в tcsh) направлять стандартный вывод и стандартную ошибку в разные места. Я обнаружил, что сценарий должен был выглядеть так:

echo 1abc
echo 1ABC >>& /dev/stderr
echo 2abc
echo 2ABC >>& /dev/stderr

Если вы не используете >>, то при перенаправлении скрипта вы потеряете некоторые из стандартных входных и / или стандартных выходных данных. Тем не менее, перенаправление вывода скрипта в файл с помощью простого> & не работает; он также теряет часть стандартной ошибки (даже на bash). Вы должны использовать

(SCRIPT >! file.out ) >&! file.err

построить. Здесь либо файл, либо оба могут быть /dev /tty для вывода на экран. (Если вы не перенаправляете вывод скрипта, проблем не возникает.)

Обратите внимание, что ничего из этого странного не происходит, если вы указываете на стандартную ошибку изнутри программы.

Также обратите внимание, что это было в Linux (Ubuntu-MATE LTS 16.04, если быть точным). Конечно, вам нужно как минимум /dev /stderr для того, чтобы все вышеперечисленное можно было использовать

После публикации я обнаружил еще одну проблему. Если вы поместите программу, которая пишет в стандартную ошибку после строки 1ABC, то 1ABC потеряется, если вы направите стандартную ошибку в файл. Хорошей новостью является то, что в моем случае стандартная ошибка должна продолжать идти в /dev /tty. Gee. :)

Для упрощения модификации и систем без /dev /stderr я решил реализовать это с помощью следующих двух строк заголовка

alias stderr echo ; if (-ew /dev/stderr) alias stderr 'echo \!* >> /dev/stderr'
which echo_err > /dev/null ; if !($status) alias stderr echo_err

Это позволяет пользователю поставить скрипт sh echo_err,

#!/bin/sh
echo $* 1>&2

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

Еще одно дополнение: мой пост выше касался проблем с перенаправлением в /dev /stderr в tcsh. Но пока я даю псевдонимы, может быть, мне следует также дать один для решения Глена Рагана, что действительно очень хорошо, если вы не возражаете против активации изображений. определять

alias 1to2 '\!* | sh -c "cat 1>&2"'
alias 2to1 '\!* |& cat'

Затем вы можете предшествовать любой команде, для которой вы хотите, чтобы стандартный вывод был перенаправлен на стандартный вывод 1to2. Это действует тогда так же, как и перед командой 1> & 2 в других оболочках, включая DOS. И это не глючит в Linux. Тогда тоже может быть 2to1. :)

OOPS: незначительный недостаток в 1to2 выше: если команда записывает как стандартный вывод, так и стандартную ошибку, порядок неправильный. Стандартные ошибки команды заканчиваются раньше, чем стандартные выходные данные окончательного стандартного результата ошибки. Решение простое; изменить | в | &:

alias 1to2 '\!* |& sh -c "cat 1>&2"'

Извини за это.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .