Добавление работ без>> при перенаправлении стандартного вывода и ошибки

Выражение замены пропускало наклонную черту конца, например.

sed 's/@driver.quit/#@driver.quit' set_QA_district_name_spec.rb 

должен быть

sed 's/@driver\.quit/#@driver.quit/' set_QA_district_name_spec.rb 

После того как это работало, я добавил -i ('оперативный') флаг так сам файл был на самом деле заменен, например.

sed -i 's/@driver\.quit/#@driver.quit/' set_QA_district_name_spec.rb 
4
23.01.2015, 17:44
2 ответа

TL; удар DR открывает и усекает все включенные файлы, прежде чем что-либо будет записано в них. stdout и stderr оба отправляется в новый , потому что удар уже имеет усеченный файл (дважды), когда ls начинает печатать.

Это - то, как удар готовится/обрабатывает перенаправление ввода-вывода. Когда вы просите команду быть перенаправленными (> ) в файл, , удар в основном открывает тот файл, создавая его при необходимости. Если файл уже существует, это является усеченным. Это сделано через открытый системный вызов и несколько флагов в вашем случае:

open("new", O_WRONLY|O_CREAT|O_TRUNC, 0666)

O_CREAT создает файл, если он не существует, в то время как O_TRUNC усекает его, когда он делает. Это открытый системный вызов является частью удар инициализация для перенаправления, означая это при использовании нескольких операций перенаправления, такой как в...

$ ls test test.txt > new 2>new

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

open("new", O_WRONLY|O_CREAT|O_TRUNC, 0666)
open("new", O_WRONLY|O_CREAT|O_TRUNC, 0666)

Это означает, что в основном, при выполнении команды, удар делает следующее (в том порядке):

  1. Открывают , новый как стандартный вывод, создают/усекают файл при необходимости.
  2. Открывают , новый как стандартная погрешность, создают/усекают файл при необходимости.
  3. Выполнение ls: это запишет содержание в новый .

, Как вы видите, , удар усекает все включенные файлы прежде запуск ls. Это означает, что при выполнении чего-то с ...> новый 2> новый , новый является в основном усеченным "дважды", и затем , выводы перенаправляются к нему. Поведение, которое вы ожидаете, потребовало бы удар получать ls stdout и stderr независимо, и открывать их один за другим, непосредственно перед записью. В основном:

  1. Запускаются ls.
  2. , Когда что-то прибудет в stdout, откройте , новый , усеките его и запишите в него.
  3. Когда что-то появляется на stderr , снова откройте new , усечите его и запишите в него.

Однако сообщения могут выходить переплетенными: перенаправленная программа вполне может написать что-то на stdout , затем что-то другое на stderr , а затем вернуться на stdout ... Было бы ужасно управлять всем этим (и это может привести к нежелательному (неопределенному?) поведению...) .

5
27.01.2020, 20:51

Вы не добавляете оба содержания. Вы получите странный результат:

$ ls testasdasd qtsingleapp-homecu-bcbf-3e8 >new 2>new
$ cat new
qtsingleapp-homecu-bcbf-3e8
: No such file or directory

Если у вас есть оба содержимого, вы должны увидеть:

$ ls testasdasd qtsingleapp-homecu-bcbf-3e8 >new 2>&1
$ cat new
ls: cannot access testasdasd: No such file or directory
qtsingleapp-homecu-bcbf-3e8

Итак, давайте сделаем strace , чтобы увидеть, что произошло:

$ strace -f -e trace=open,close,write,fcntl,dup2 sh -c 'ls testasdsad qtsingleapp-homecu-bcbf-3e8 > new 2>new'
open("/etc/ld.so.cache", O_RDONLY)      = 3
close(3)                                = 0
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY) = 3
close(3)                                = 0
open("new", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
fcntl(1, F_DUPFD, 10)                   = 10
close(1)                                = 0
fcntl(10, F_SETFD, FD_CLOEXEC)          = 0
dup2(3, 1)                              = 1
close(3)                                = 0
open("new", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
fcntl(2, F_DUPFD, 10)                   = 11
close(2)                                = 0
fcntl(11, F_SETFD, FD_CLOEXEC)          = 0
dup2(3, 2)                              = 2
close(3)                                = 0
Process 7523 attached
....
[pid  7523] write(2, "ls: ", 4)         = 4
[pid  7523] write(2, "cannot access testasdsad", 24) = 24
[pid  7523] open("/usr/share/locale/en_US/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid  7523] open("/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid  7523] write(2, ": No such file or directory", 27) = 27
[pid  7523] write(2, "\n", 1)           = 1
[pid  7523] write(1, "qtsingleapp-homecu-bcbf-3e8\n", 28) = 28
[pid  7523] close(1)                    = 0
[pid  7523] close(2)                    = 0
Process 7523 detached
--- SIGCHLD (Child exited) @ 0 (0) ---
dup2(10, 1)                             = 1
close(10)                               = 0
dup2(11, 2)                             = 2
close(11)                               = 0

Посмотрите на последовательности open , fcntl , dup2 вы можете увидеть:

  • Во-первых, файл new открыт и назначен файловому дескриптору 3
  • ​​Затем дескриптор файла 1 дублируется в дескриптор файла 10
  • Затем дескриптор файла 3 (который является файлом new ) дублируется в файл дескриптор 1 (сейчас это 10 ).

Все вышеперечисленное относится к > new в вашей команде. Затем произошли те же последовательности, но для дескриптора файла 2 см. 2> new в вашей команде.

После этого у вас есть два дескриптора файла 10 и 11 , оба указывают на новый файл, и эти дескрипторы становятся stderr и stdout ] из LS . Когда ls запущен, он пишет в оба stderr и stdout , которые указывают на один и тот же файл new , и часть вывода была обрезана, потому что stdout перезаписал stderr .

2
27.01.2020, 20:51

Теги

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