Если я хочу, чтобы содержимое file2
совпадало с содержимым file1
, я мог бы просто запустить cp file1 file2
.
Однако, если я хочу , чтобы сохранить все о file2
кроме Содержанию-владельца, права доступа, расширенные атрибуты, списки управления доступом, жесткие ссылки и т.д., и т.д., то я не хотел бы работать cp
. * В этом случае я просто хочу , чтобы хлопнуть содержание file1
в file2
.
Похоже, что следующий будет делать это:
< file1 > file2
Но это не работает. file2
обрезается до нуля и не записывается. Тем не мение,
cat < file1 > file2
делает работу.
Меня удивило, что первая версия не работает.
Вторая версия - UUOC? Есть ли способ сделать это без вызова команды, просто с помощью перенаправлений?
Примечание: я знаю, что UUOC является скорее педантичным, чем настоящим анти-паттерном.
* Как обнаружил tniles09 , на самом деле cp
будет работать в этом случае.
источник
< file1 > file2
Делает ли то, что вы хотите, зависит от оболочки.<
...file1
не существует, или же невозможно прочитать, и вы открываете его<
до открытия>
вывода, а затем подумайте, что произойдет, если выcat
попытаетесь открыть его.cat
(по умолчанию), по сути, запускающая вторую команду. См. Ответ Стефана Шазеласа ниже, чтобы больше узнать об этом, чем вписывается в комментарий.Ответы:
cat < file1 > file2
это не UUOC. Классически,<
и>
делать перенаправления, которые соответствуют дублированию файловых дескрипторов на системном уровне. Дублирование файловых дескрипторов само по себе ничего не делает (ну,>
перенаправления открываютсяO_TRUNC
, поэтому, если быть точным, перенаправления вывода обрезают выходной файл). Не позволяйте<
>
символам смущать вас. Перенаправления не перемещают данные - они назначают файловые дескрипторы другим файловым дескрипторам.В этом случае вы открываете
file1
и назначаете этот дескриптор файла дескриптору файла0
(<file1
==0<file1
)file2
и назначаете этот дескриптор файла дескриптору файла1
(>file2
==1>file2
).Теперь, когда у вас есть два файловых дескриптора, вам нужен процесс для объединения данных между ними - и это то, что нужно
cat
.источник
Это не так, потому что, как отмечали другие, рассматриваемое поведение зависит от оболочки. Как вы (ОП) указали, это немного педантично , может быть, даже смешно? вроде темы.
Однако, в системах GNU, ваша начальная предпосылка имеет другое доступное решение:
cp --no-preserve=all file1 file2
. Попробуйте, я думаю, что это удовлетворит вашу описанную ситуацию (например, изменение содержимогоfile2
без изменения его атрибутов).Пример :
ОБНОВЛЕНИЕ На самом деле, я только что заметил, что моя система
cp
сама по себе, кажется, сохраняет атрибуты, если-a
или-p
не указано. Я использую оболочку bash и GNU coreutils. Я думаю, вы узнаете что-то новое каждый день ...Результаты теста (по Wildcard), включая жесткую ссылку и различные разрешения:
источник
В
zsh
оболочке, где< file1 > file2
работает, оболочка вызываетcat
.Для командной строки, которая состоит только из перенаправлений и не содержит ни команд, ни назначений,
zsh
вызывается$NULLCMD
(cat
по умолчанию), если только перенаправление не является<
единственным, в котором вместо этого вызывается$READNULLCMD
(pager
по умолчанию). (это еслиzsh
не вsh
илиcsh
эмуляция, в этом случае он ведет себя как оболочки, которые он эмулирует).Так:
на самом деле так же, как
а также
такой же как
источник
не работает, потому что там нет команды; нет процесса. Оболочка открывает / создает файлы и упорядочивает перенаправления (это означает, что файловые дескрипторы, ссылающиеся на эти файлы, установлены в 0 и 1: стандартный ввод и стандартный вывод). Но там нечего делать, чтобы выполнить цикл для чтения из стандартного ввода и записи в стандартный вывод.
zsh
делает эту работу, подставляя настраиваемую пользователем команду в этом случае «пустой команды». Команда не отображается в командной строке, но она все еще там. Для него создан процесс, и он работает так же.NULLCMD
этоcat
по умолчанию, так что на< from > to
самом деле означаетcat < from > to
, что вzsh
, еслиNULLCMD
не будет установлен на что - то еще; это команда «скрытого кота».«Бесполезное использование cat» происходит, когда
cat
используется как посредник для чтения из файла и передачи данных другому процессу, дескриптор файла которого может быть просто подключен к исходному файлу.Если его
cat
можно удалить из ситуации, чтобы оставшиеся команды могли выполнять ту же задачу, это бесполезно. Если это не съемный, то это не бесполезно.cat
Что заменяемое это не то же самое. Например, вместо того,cat > file
чтобы использоватьvi file
файл для создания файла. Это не считается удалениемcat
при использовании того, что осталось для достижения той же задачи.Если
cat
это единственная команда в конвейере, то, конечно, ее нельзя удалить; никакая перестановка того, что осталось, не сделает эквивалентную работу.Некоторые сценарии оболочки используют,
cat
потому что они думают, что это позволяет им перемещать входной операнд ближе к левой стороне командной строки. Тем не менее, перенаправления могут быть в любом месте командной строки:источник
f -
для tar.tar xf -
это простоtar x
.cat
участвует в создании файла? Ответ ясно говорит, что оболочка делает это. На какую проблему> file
вы ссылаетесь? Я часто использую его один для усечения существующего файла до нулевой длины или для гарантии того, что он существует. Этот вопрос о том, почему< from > to
не работаетcat < from > to
, а UUoC, а не "пожалуйста, назовите мне причины, почемуcat
не является хорошей заменойcp
".tar
это архиватор ленты . Многиеtar
реализации по-прежнему работают с первым ленточным устройством по умолчанию.< file1 > file2
Кажется, зависит от оболочки, на Zsh это работает, на Bash нет.редактировать: удалено ложное утверждение
источник
cp -a
сохраняет атрибуты file1 и перезаписывает атрибуты file2. Напротив желаемого поведения. Кроме того, я не могу сказать, даже просматривая справочную страницу, что произойдет с жесткими ссылками, но я думаю, что можно с уверенностью сказать, что жесткие ссылки file2 не будут сохранены.В дополнение ко всем хороших ответов, вы можете избежать UUOC путем имитации
cat
:Эти команды не копируют метаданные файла, как обычные
cp
.источник
cat
. Здесь вам нужна команда для переноса данных между двумя файловыми дескрипторами, и онаcat
является одной из лучших для этого. Смотрите также,pv
что можно использоватьsplice()
в Linux для fifos (хотя это не так,fadvise(POSIX_FADV_SEQUENTIAL)
как в GNUcat
).dd
для двоичных файлов кажется хорошей ... или будетcat
работать так же хорошо для двоичных файлов?cat
также работает для двоичных файлов (Unix, как правило, не различает; однако некоторые инструменты специально работают построчно, такие как awk, grep, wc, ... POSIX также определяет минимальную наибольшую длину строки, поэтому в теории инструмент, ориентированный на строки, может отказаться от работы с чрезмерно большими линиями.)sed '' < file1 > file2
;-)Если это работает, не исправляйте это.
я хотел бы использовать
и не парься на ПК от семантики.
источник