Grava string em um arquivo sem shell [closed]

4

Suponha que eu tenha um ambiente onde não exista um shell rodando, então eu não posso usar redirecionamento, pipes, aqui-documentos ou outros shell-isms, mas eu posso lançar um comando ( através de execvp ou de alguma forma similar). Eu quero escrever uma seqüência arbitrária para um arquivo nomeado. Existe um comando padrão que fará algo como:

somecommand  outputfile 'string'

por exemplo:

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

Um exemplo muito burro pode ser:

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

onde eu configuro o 1.txt para conter a string que eu quero.

Existe um comando comum que pode ser usado para fazer isso?

    
por user1908704 28.07.2018 / 01:01

2 respostas

7

Se você souber de qualquer outro arquivo não vazio no sistema, então com POSIX sed :

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

Com o GNU sed e apenas o seu próprio arquivo não vazio, você pode usar:

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

Com BSD sed , isso funcionaria:

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

Se você não estiver usando um shell, presumivelmente o linebreak não é um problema.

Com ex , se o arquivo de destino existir:

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

Isso exclui tudo no arquivo, substitui a primeira linha por "hello world", depois escreve e sai. Você poderia fazer a mesma coisa com vi no lugar de ex . Não são necessárias implementações para suportar várias opções de -c , mas elas geralmente são. Para muitas implementações de ex , o requisito de que o arquivo já exista não é imposto.

Além disso, com awk :

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

irá escrever "hello world" para o arquivo "foo".

Se houver arquivos contendo os bytes desejados em locais conhecidos, você poderá montar um byte by byte de arquivo em vários comandos com dd (nesse caso, alphabet contém o alfabeto, mas pode ser um mix de arquivos de entrada):

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

A partir daí, apenas cp regular funcionará ou você poderá colocá-lo no local para começar.

Menos comumente, o comando mispipe de moreutils permite construir um canal sem shell:

mispipe "echo 1" "tee wtarget"

é equivalente a echo 1 | tee wtarget , mas retorna o código de saída de echo . Isso usa a função system() internamente, o que não estritamente requer um shell para existir.

Por fim, perl é um comando comum e permite que você grave programas arbitrários para fazer o que quiser na linha de comando, assim como python ou qualquer outra linguagem de script comum. Da mesma forma, se um shell não estiver "executando", mas existir, sh -c 'echo 1 > target' funcionará bem.

    
por 28.07.2018 / 02:10
5

Você pode usar awk :

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

Quando um programa awk consiste em apenas uma instrução BEGIN , ele apenas interpreta essa instrução e não processa nenhuma entrada.

Você pode até parametrizar isso

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

Embora com essa sintaxe, você precisa escapar dos caracteres de barra invertida. Usar ARGV não tem o problema:

awk 'BEGIN {print ARGV[1] > ARGV[2]}' World /tmp/main
    
por 28.07.2018 / 01:28