Это может произойти в x86_64 и мультибиблиотечном пакете. yum remove libstdc ++
пытается удалить 64-битную версию, но она не установлена. Поэтому в такой ситуации вам следует обратиться к пакету с помощью arch. То есть:
yum remove libstdc++-4.1.2-55.el5.i386
Эта возможность была введена в ksh
(впервые документирована в ksh86) и использовала возможность /dev/fd/n
(добавленную независимо в некоторых BSD и AT&T системах ранее). В ksh
и вплоть до ksh93u это не будет работать, если в вашей системе нет поддержки /dev/fd/n. zsh, bash и ksh93u+
и выше могут использовать временные именованные трубы (именованные трубы добавлены в SysIII, я полагаю), где /dev/fd/n недоступны.
На системах, где /dev/fd/n
доступны (POSIX не определяет их), вы можете сделать подстановку процессов самостоятельно (diff <(cmd1) <(cmd2)
) с помощью:
{
cmd1 4<&- | {
# in here fd 3 points to the reading end of the pipe
# from cmd1, while fd 0 has been restored from the original
# stdin (saved on fd 4, now closed as no longer needed)
cmd2 3<&- | diff /dev/fd/3 -
} 3<&0 <&4 4<&- # restore the original stdin for cmd2
} 4<&0 # save a copy of stdin for cmd2
Однако это не работает с ksh93
в Linux, поскольку там shell pipes реализованы с помощью socketpairs, а не pipes, и открытие /dev/fd/3
, где fd 3 указывает на сокет, не работает в Linux.
Хотя POSIX не определяет /dev/fd/n
. Он определяет именованные трубы. Именованные трубы работают как обычные трубы, за исключением того, что вы можете получить к ним доступ из файловой системы. Проблема здесь в том, что вы должны создавать временные и очищать их после этого, что трудно сделать надежно, особенно учитывая, что POSIX не имеет стандартного механизма (например, mktemp -d
, как в некоторых системах) для создания временных файлов или каталогов, и переносимая обработка сигналов (очистка после зависания или убийства) также трудно переносима.
Вы можете сделать что-то вроде:
tmpfifo() (
n=0
until
fifo=$1.$$.$n
mkfifo -m 600 -- "$fifo" 2> /dev/null
do
n=$((n + 1))
# give up after 20 attempts as it could be a permanent condition
# that prevents us from creating fifos. You'd need to raise that
# limit if you intend to create (and use at the same time)
# more than 20 fifos in your script
[ "$n" -lt 20 ] || exit 1
done
printf '%s\n' "$fifo"
)
cleanup() { rm -f -- "$fifo"; }
fifo=$(tmpfifo /tmp/fifo) || exit
cmd2 > "$fifo" & cmd1 | diff - "$fifo"
rm -f -- "$fifo"
(здесь не рассматривается обработка сигналов).
Если нужно избежать потери переменной в полезном cmd | while read A B C
, вместо:
VAR="before"
while read A B C
do
VAR="$A $VAR"
done < <(cmd)
echo "$VAR"
вы можете использовать:
VAR="before"
while read A B C
do
VAR="$A $VAR"
done << EndOfText
`cmd`
EndOfText
echo "$VAR"
Итак, чтобы ответить на вопрос:
sort file1 | diff /dev/stdin /dev/stdout 2<<EOT
`sort file2`
EOT
Для этого можно использовать файлы heredoc и /dev/fd/n. Например, в bash
можно сделать так:
#!/usr/bin/env bash
paste <(echo "$SHELL") <(echo "$TERM") <(echo "$LANG")
но в POSIX sh вы должны сделать это:
#!/bin/sh
paste /dev/fd/3 3<<-EOF /dev/fd/4 4<<-EOF /dev/fd/5 5<<-EOF
$SHELL
EOF
$TERM
EOF
$LANG
EOF
Вывод такой же.
И чтобы ответить на вопрос, это работает:
#!/bin/sh
diff /dev/fd/3 3<<-EOF /dev/fd/4 4<<-EOF
$(sort file1)
EOF
$(sort file2)
EOF
Выглядит неуклюже, но работает.