Верно ли заключить, что существует 4 типа ** вывода **, которые мы можем ссылаться на файл в Linux?

Похоже, вы путаете здесь два свойства ZFS:

  • Копирование при записи (CoW) - это описание того, как файловая система работает при изменении файлов. Традиционные (не CoW) файловые системы имеют цикл чтения-изменения-записи, где обновления файла выполняются на месте, что означает, что единственная копия файла изменяется напрямую (запись обновленных байтов в указанной позиции внутри файла ). В случае пропадания питания возможно повреждение.Это не относится к файловым системам CoW, таким как ZFS, где любая модификация файла никогда не затрагивает файл: измененные байты просто добавляются, и в случае успеха старые части помечаются как удаляемые. Это предотвращает потерю целостности за счет большей фрагментации (поскольку для каждого изменения требуется новое пространство).
  • Дедупликация - это дополнительная функция, которую можно включить в файловых системах ZFS (по умолчанию отключено). Если этот параметр включен, любые записываемые данные сначала просматриваются в таблице дедупликации (DDT). Если он уже существует, он не записывается снова, а только связывается. Это работает при передаче (чтение и запись), но не для уже дублированных сохраненных «старых» данных. У него также есть определенные недостатки, которые вы можете прочитать в Интернете, поэтому я не буду их здесь описывать.

Если вы никогда не включали дедупликацию в своей файловой системе, любая копия ( cp , копия в Finder и т. Д.) Создаст новые данные и уменьшит ваше полезное пространство. Встроенной дедупликации по умолчанию нет (даже рекомендуемое сжатие по умолчанию отключено!). Вы можете убедиться в этом сами, скопировав файл размером 1 МБ 1000 раз, вы потеряете 1000 МБ места вместо 1 МБ.

Как я могу определить, какие дубликаты файлов являются дубликатами друг друга, копируемыми при записи?

Вы не можете, но вы можете использовать средство проверки дубликатов, как вы, для поиска точных дубликатов (как в любой другой файловой системе ). Вы также можете использовать zdb -b poolname , чтобы оценить преимущества дедупликации , чтобы увидеть, будет ли увеличение ОЗУ полезным для вашего случая.Кроме того, включение сжатия поможет в любом случае, поэтому, если вы еще не используете его, включите его.

1
21.08.2018, 04:00
3 ответа

К каждому процессу в системе Unix подключено два потока вывода: стандартный вывод (stdout, файловый дескриптор 1) и стандартная ошибка ( stderr, файловый дескриптор 2). Они могут быть перенаправлены независимо друг от друга. Стандартный ввод использует дескриптор файла 0.

  • Чтобы перенаправить стандартный вывод в файл файл , используйте > file или более явное 1> файл . Замените файл на / dev / null , чтобы удалить данные.
  • Чтобы перенаправить стандартную ошибку в файл файл , используйте 2> файл .
  • Чтобы перенаправить стандартную ошибку туда, где идет стандартный вывод, используйте 2> & 1 .
  • Чтобы перенаправить стандартный вывод туда, где происходит стандартная ошибка, используйте 1> & 2 .

Не существует понятия «конечный результат» потока или процесса.Я полагаю, что все, что отправляется на стандартный вывод, может быть воспринято как «результат» процесса, если только он не выводит данные в какой-то файл, который открывается сам по себе, или имеет другие побочные эффекты (например, отсоединение файла от каталога в случае of rm , или обработка ряда сетевых подключений, в случае sshd ). Процесс также возвращает статус выхода (ноль для «успеха» и ненулевое значение для «неудачи»), который можно рассматривать как «результат» этого процесса, но это не обязательно связано с потоками вывода процесса.

Потоки также могут быть перенаправлены в режиме добавления , что означает, что если перенаправление выполняется в файл, этот файл изначально не будет усечен, а любые данные в потоке будут добавлены в конец. файла. Для этого можно использовать >> файл вместо > файл .

В примечании к вопросу дается команда

find / -type f -name php.ini 2>/dev/null

. Это перенаправляет (отбрасывает) только стандартную ошибку . Стандартный выходной поток вообще не перенаправляется и поэтому будет полностью виден в консоли или терминале. Если бы это была промежуточная часть конвейера, стандартный выходной поток подавался бы на стандартный ввод следующей команды конвейера.

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

4
27.01.2020, 23:13

Каждый процесс по соглашению может использовать три стандартных файловых дескриптора. Эти файловые дескрипторы доступны в виде потоков: stdin , stdout и stderr .

По умолчанию, когда вы запускаете процесс из оболочки (CLI), первый подключается к входу вашего терминала (или эмулятора терминала, такого как xterm), а два других подключаются к выходу вашего терминала.

Вы можете указать оболочке перенаправить их в другое место, например, в / dev / null (где они просто поглощаются). И вы можете сделать это независимо для stdout и stderr . Итак, для этого случая действительно есть четыре возможности:

command 
command > /dev/null
command 2> /dev/null
command > /dev/null 2> /dev/null

Но ничто не мешает вам перенаправить один или оба в другое место:

command > /tmp/myout 2> /tmp/myerr

В этом случае вы также не получите вывода в своем терминале, но вы можете прочитать его позже в файлы / tmp / myout и / tmp / myerr .

3
27.01.2020, 23:13

Ситуация и проще, и сложнее, чем предполагает ваш вопрос. Перефразируя то, что Кусалананда говорит в своем ответе, есть два стандартных (обычных) потока ввода/вывода (файловые дескрипторы) которые традиционно настроены и используются для вывода: stdout (файловый дескриптор1) и stderr (файловый дескриптор2). Наш канонический вопрос, Что такое операторы управления и перенаправления оболочки?, обсуждает, как перенаправить их. Наивно, мы можем перечислить пять различных комбинаций:

╔══════════════════════════════╦═════════════════════════════════════════════╗
║                              ║                   stderr                    ║
║                              ╟─────────────────────┬───────────────────────╢
║                              ║       default       │                       ║
║                              ║ (same as the shell) │       redirected      ║
╠════════╤═════════════════════╬═════════════════════╦═══════════════════════╣
║        │       default       ║                     ║                       ║
║        │ (same as the shell) ║          1          ║           2           ║
║        ├─────────────────────╠═════════════════════╬═══════════════════════╣
║ stdout │                     ║                     ║ 4. redirected         ║
║        │                     ║                     ║    to the same file   ║
║        │      redirected     ║          3          ╟───────────────────────╢
║        │                     ║                     ║ 5. redirected         ║
║        │                     ║                     ║    to different files ║
╚════════╧═════════════════════╩═════════════════════╩═══════════════════════╝

, но если вы считаете /dev/null отличными от файла, и добавить режим как частный случай, и режим чтения-записи отличается от режима только записи, и трубы как отличные от файлов, тогда количество комбинаций увеличивается в геометрической прогрессии. Однако, как неоднократно заявлялось, «конечный результат stdout» не является стандартной фразой Unix/Linux/bash.

Только два?

Другие ответы (возможно, мудро) ограничились на stdout и stderr (файловые дескрипторы 1 и 2). Я (опрометчиво?) считаю, что полный ответ на этот вопрос следует учитывать тот факт, что доступны другие файловые дескрипторы — до сотен, тысяч или даже более миллиона. Например, если вы запустите команду вида difffile1file2, программа diff откроет файл1 и файл2, и ядро, вероятно, назначит файловые дескрипторы 3 и 4. Разница в том, что предопределены только файловые дескрипторы 0, 1 и 2. Перенаправление файловых дескрипторов выше 2 обсуждается в следующих местах:

Например, см. этот пример высокого дескриптора файла:

$ cat canine.c
#include <stdio.h>
#include <string.h>

main()
{
        int     i, len;
        char    msg[] = "Hello, dog.\n";

        len = strlen(msg);
        i = write(17, msg, len);
        if (i == len)
                printf("Success!  i = %d = len\n", i);
        else if (i == -1)
            {
                printf("Error!  i = %d (len = %d)\n", i, len);
                perror("");
            }
        else
                printf("Unexpected result: i = %d, len = %d\n", i, len);
}

$ make canine
cc     canine.c   -o canine

$ ./canine
Error!  i = -1 (len = 12)
Bad file descriptor

$ ./canine 17> animal
Success!  i = 12 = len

$ ls -l
total 70
-rw-r--r-- 1 myusername mygroupname    12 Apr 12 13:36 animal
-rwxr-xr-x 1 myusername mygroupname 67067 Apr 12 13:36 canine
-rw-r--r-- 1 myusername mygroupname   358 Apr 12 13:36 canine.c

$ cat animal
Hello, dog.

Предупреждение: я не уверен, что приведенное выше будет работать для всех версий всех оболочек.

Стандартные программы не пишут в файловые дескрипторы выше 2. (если только они не получили этот файловый дескриптор от ядра открыв файл, установив сетевое подключение или что-то в этом роде). Но если у вас есть (нестандартная) программа, которая делает это, вы можете перенаправить эти файловые дескрипторы.

И если у вас всего 100 файловых дескрипторов, и вы считаете только, перенаправляется ли каждый из них или нет, у вас более нониллиона (1 000 000 000 000 000 000 000 000 000 000) возможные комбинации.

0
27.01.2020, 23:13

Теги

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