Intereting Posts
Используя startx на Fedora 17, пользователь без полномочий root не может присоединиться к новым беспроводным сетям – как исправить? Как написать столбец последовательных целых чисел в Vim над существующим текстом? Почему rm * (1) * удаляет все файлы в каталоге? Почему ln -s создает относительные сломанные ссылки? Переключение между двумя окнами в Linux Создание GCC внутри chroot из источника Как установить шаблоны и пакеты одновременно? Получение уровня версии FreeBSD для загрузочной среды ZFS, которая смонтирована, но не загружена Мониторинг процессов с использованием только системных вызовов (без утилит, таких как `top`) разделяя команду на одну строку на две части, чтобы она была более «структурирована» эстетически Вопрос о переменных в файле / etc / inputrc Каковы могут быть причины, по которым сценарии оболочки убивают себя? видимые Ethernet-кадры наблюдаются частично, когда интерфейс MTU меньше, чем снятые кадры fdisk – по умолчанию для non Dos, но все же использует Dos disklabel Значение суммы рядом с определенным шаблоном

Записать строку в файл без оболочки

Предположим, у меня есть среда, в которой не запущена shell, поэтому я не могу использовать redirect, каналы, здесь-документы или другие оболочки, но я могу запустить команду (через execvp или другим подобным способом). Я хочу написать произвольную строку в именованный файл. Есть ли стандартная команда, которая будет делать что-то вроде:

 somecommand outputfile 'string' 

например:

 somecommand /proc/sys/net/ipv4/ip_forward '1' 

Действительно тупой пример может быть:

 curl -o /proc/sys/net/ipv4/ip_forward http://example.com/1.txt 

где я установил 1.txt, чтобы содержать строку, которую я хочу.

Есть ли общая команда, которой можно злоупотреблять, чтобы сделать это?

Если вам известен любой другой непустой файл в системе, то с помощью POSIX sed :

 sed -e 's/.*/hello world/' -e 'wtarget' -eq otherfile 

С GNU sed и просто вашим непустым файлом вы можете использовать:

 sed -i.bak -e '$ihello world' -e 'd' foo 

С BSD sed это будет работать вместо:

 sed -i.bak -e '$i\ hello world' -ed foo 

Если вы не используете оболочку, то, вероятно, перенос строки не является проблемой.


С ex , если целевой файл существует:

 ex -c '0,$d' -c 's/^/hello world/' -c 'x' foo 

Это просто удаляет все в файле, заменяет первую строку на «hello world», затем записывает и завершает работу. Вы можете сделать то же самое с vi вместо ex . Реализации не обязаны поддерживать несколько опций -c , но обычно они делают. Для многих реализаций ex требование о том, что файл уже существует, не применяется.


Также с awk :

 awk -v FN=foo -v STR="hello world" 'BEGIN{printf(STR) > FN }' 

напишет “привет мир” в файл “foo”.


Если в известных местах существуют файлы, содержащие нужные вам байты, вы можете собрать файл побайтно по нескольким командам с помощью dd (в этом случае alphabet содержит алфавит, но это может быть смесь входных файлов):

 dd if=alphabet bs=1 skip=7 count=1 of=test dd if=alphabet bs=1 skip=4 count=1 seek=1 of=test dd if=alphabet bs=1 skip=11 count=1 seek=2 of=test dd if=alphabet bs=1 skip=11 count=1 seek=3 of=test dd if=alphabet bs=1 skip=14 count=1 seek=4 of=test cat test hello 

Оттуда будет работать только обычный cp , или вы могли бы начать с него.


Реже команда mispipe из moreutils позволяет создать канал без оболочки:

 mispipe "echo 1" "tee wtarget" 

эквивалентно echo 1 | tee wtarget echo 1 | tee wtarget , но возвращающий код выхода echo . При этом внутренне используется функция system() , которая не требует строго оболочки.


Наконец, perl – это обычная команда, которая позволяет вам писать произвольные программы для выполнения в командной строке чего угодно, как и python или любой другой распространенный язык сценариев. Точно так же, если shell просто не «работает», но существует, sh -c 'echo 1 > target' будет работать нормально.

Вы можете использовать awk :

 awk 'BEGIN {print "Hello" > "/tmp/file"}' 

Когда программа awk состоит только из оператора BEGIN , она просто интерпретирует этот оператор и не обрабатывает ввод.

Вы даже можете параметризовать это

 awk -v text="World" -v file="/tmp/main" 'BEGIN {print text > file}' 

Хотя с этим синтаксисом вам нужно будет экранировать символы обратной косой черты. Использование ARGV не имеет проблемы:

 awk 'BEGIN {print ARGV[1] > ARGV[2]}' World /tmp/main