Создайте 2 файла с похожим именем с содержимым из 2-строчного вывода команды

Я выполняю cmd и выводит 2 строки текста:

 $ cmd foo bar 

Мне нужно написать их: `/long/path/x.{load,conf}

Для записи в этот пункт назначения требуется привилегия суперпользователя, которая вручную запрещает:

 $ echo "foo" > /long/path/x.load $ echo "bar" > /long/path/x.conf 

поскольку «перенаправление выполняется до начала команды (sudo) и получает привилегию»

Учитывая, что foo и bar сами являются заполнителями для громоздких текстовых строк, что это хороший способ сделать это?

Я действительно ищу решение, которое вызывает наименьшее количество царапин на голове, поскольку это представляет собой шаг в последовательности инструкций, и было бы неплохо написать код, который говорит сам за себя, однако меня всегда интересуют все возможные способы сделай что-нибудь.

  • Перенаправить stdin и stdout в порты
  • Разница между «cat <file.txt» и «echo <file.txt»
  • Управление терминалом в середине трубы
  • Меню KSH, основанное на тексте, с использованием STDERR
  • Скройте вывод bash во время запуска автоматического сценария.
  • Обнаружение захваченного портала, всплывающая реализация?
  • Как получить дескриптор файла, отличный от stdin stdout и stderr (чтобы сделать что-то вроде $ program 1> file_1 3> file_2)?
  • exec <filename - что это делает?
  • 3 Solutions collect form web for “Создайте 2 файла с похожим именем с содержимым из 2-строчного вывода команды”

    Оператор перенаправления Awk пригодится здесь. Вот несколько вариантов этой темы.

     cmd | sudo awk '{print >"/long/path/x." (NR==1 ? "load" : "conf")}' cmd | sudo x=/long/path/x awk 'NR==1 {print >ENVIRON["x"]".load"} NR==2 {print >ENVIRON["x"]".conf"}' cmd | sudo awk 'FNR==1 && NR!=1 {exit} {print >ARGV[NR-1]}' - /long/path/x.{load,conf} 

    Первый из них самый короткий и примерно такой же простой, как и он. Каждая строка печатается в имя файла, определяемое путем вычисления выражения после оператора > . Текущий номер строки NR используется для вычисления имени файла. Сопоставление выражений является оператором конкатенации строк в awk.

    Люди обычно делают это с tee :

     cmd | sudo tee /long/path/x.{load,conf} 

    tee записывает копии своего ввода во все его именованные выходные файлы – и таким же образом перенаправление происходит перед exec а также генерирует аргумент в расширении скобки. Таким образом, вышеизложенное должно работать нормально и записывать оба результирующих имени файла сразу и стандартное.

    Если вы предпочитаете не видеть, что пишет tee на вашем терминале, поскольку он копирует данные, вы можете перенаправить стандартную версию на /dev/nullsudo не будет мешать этому перенаправлению.

    Следует отметить, что это – как написано – tee будет обрезать выходные файлы перед тем, как писать им. Если вы хотите добавить вместо этого, вы можете просто добавить ключ -a ppend, и tee скопирует входные данные в хвост всех именованных выходных файлов.

    По правде говоря, писать каждую строку в отдельных местах немного сложнее. Но sed предлагает команду. Объедините его с аргументом -e xpression, и вы можете написать весь скрипт sed с расширением скобки:

     cmd | sudo sed -e'$x;/./w '/long/path/x.{load,conf}$'\n1x' 

    … приведет к первой строке в первый файл аргумента, а вторая – ко второй. E x изменяет только баланс сценария в первой и второй строках – чтобы sed записывал обе строки в оба файла для каждой строки.

    Я протестировал его так:

     printf %s\\n 1 2 | sed -e'$x;/./w '/tmp/{1,2}$'\n$!x' 

    … и потом побежал …

     head /tmp/[12] 

    … которые напечатаны …

     ==> /tmp/1 <== 1 ==> /tmp/2 <== 2 

    Я не уверен, что вы хотите, чтобы все .load решение (от команды cmd до параметров .load и .conf , но в соответствии с настройкой этого файла вы все равно можете сделать это с помощью sudo, но вам действительно нужно перенаправить быть частью команды sudoed :

     $ sudo sh -c "echo 'foo' > /long/path/x.load" $ sudo sh -c "echo 'bar' > /long/path/x.conf" 

    Здесь sudo получит более высокую привилегию, затем запустит sh shell, который, в свою очередь, будет интерпретировать данную команду, и только в этот момент произойдет перенаправление, что позволит избежать какой-либо проблемы с привилегиями.

    Если вы, возможно, захотите создать сценарий, в зависимости от ваших конкретных потребностей, это может выглядеть примерно так:

     cmd | { read line sudo sh -c "echo '$line' > /long/path/x.load" read line sudo sh -c "echo '$line' > /long/path/x.conf" } 
    Linux и Unix - лучшая ОС в мире.