Перенаправить стандартный вывод в стандартный поток ошибок в tcsh

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

echo test >&2

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

echo test > & 2

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

4 ответа

Решение

Что касается 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 не "вставлять пробелы", так как он все равно не будет интерпретировать эту последовательность по назначению.

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

Я не видел, что это был тсч. Смотрите раздел "Ввод / вывод" man tsch для деталей, включая это:

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

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

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

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

Я провел несколько экспериментов с указанием /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"'

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

Другие вопросы по тегам