O redirecionamento impossível?

Olá a todos!

Pessoal, isso atualmente não é um caso de uso real, porém, me deixou deveras intrigado!

Eu gostaria de fazer a escrita de qualquer string em algum arquivo da forma mais:

  • Built-In;
  • Barata;
  • Curta.

Que fosse possível. E também “sem utilizar nenhum comando”. Certamente o que todo mundo deve estar pensando agora mesmo seria algo parecido como:

echo 'some string' >/path/to/some/file.txt

E de fato, até o momento esse é a forma que mais atenderia os requisitos que mencionei. Porém, o que eu REALMENTE queria era algo como:

'some string' >/path/to/some/file.txt

Esse exemplo retrata bem o que eu estava querendo, porém, obviamente isso não funciona:

  • Primeiro: O shell iria tratar “'some string'” como um comando e como não é logo irá retornar 127 (command not found).

  • Segundo: Supondo que não estourasse o erro e essa string ficasse vagando. O redirecionamento ainda não iria funcionar como o esperado pois, o redirecionador > redirecionar a saída padrão de algum comando para outro lugar. Como “'some string'” seria uma “string flutuante”, ela por si só não geraria saída, logo, não teria nada a ser redirecionado.

Será que algo assim será possível algum dia? Nem que tivesse que adicionar alguma outra coisa no meio?

Por favor, deem sugestões e dicas.

O que você quer fazer é “digamos” impossível sem uma modificação na programação do código.

E a nível de desenvolvimento é ilógico aceitar qualquer termo como sendo um comando. A programação só funciona porque existe os comandos pré definidos para executar as operações.

Outra alternativa que você poderia fazer é um programa para capturar as entradas no shell, mas o que vai acontecer é apenas alterar o comando echo para outro termo que você definir.

OFF: Uso um programa para adicionar strings em determinado arquivo, talvez seja o que esteja querendo:

#!/bin/bash

# Caminho do arquivo
arquivo="$HOME/Downloads/Docs-Temp/temp.txt"

# Verifica se foi fornecido um argumento de texto
if [ "$#" -ne 1 ]; then
    echo "Uso: ./add-texto \"texto\""
    exit 1
fi

# Armazena o texto fornecido no argumento
texto=$1

# Insere o texto no arquivo usando o comando echo
echo "$texto" >> "$arquivo"

echo "Texto inserido com sucesso no arquivo $arquivo."

$ add-texto “texto”

OBS: add-texto é o comando que eu adicionei para esta operação, você pode altera-lo seguindo as opções abaixo.

PS: O comando pode ser definido por alias ou adicionando a pasta onde contem o arquivo sh ou adicionando o arquivo .sh dentro de um bin previamente adicionando ao PATH.

3 curtidas

Isso simplesmente não é a linguagem do shell. A primeira string de um comando é para se referir a um executável ou função (até porque imagine o pesadelo que seria você ter essa ambiguidade e um sistema possuir um executável chamado feito/concluido).

Se você tiver mais de uma linha que quer enviar para um arquivo e fica enfadonho ter vários >>, você pode agrupar os echo com {, explorar o fato de os quotes "/' cruzarem várias linhas ou o cat <<EOF:

{
  echo linha 1
  echo linha 2
  echo linha 3
} > arquivo.txt

echo 'linha 1
linha 2
linha 3' > arquivo.txt

cat <<\EOF > arquivo.txt
linha 1
linha 2
linha 3
EOF

Porém, em interesse da ciência, dá para abusar de um recurso do bash para viabilizar a sintaxe dos seus sonhos: a função command_not_found_handle. A intenção é a distribuição sugerir pacotes para instalação e para isso ela é executada a cada vez que um comando não é encontrado. Daí, podemos simplesmente:

#!/bin/bash
command_not_found_handle() { echo "$@"; }
'some string' > arquivo.txt
funçona também com várias palavras >> arquivo.txt

Porém, você vai ter que incluir essa função como cabeçalho. Além disso, seu script ficará “amarrado” ao bash (zsh usa outro mecanismo, e shells minimalistas como o dash não têm nada parecido) e utilidade de outros recursos do shell (como set -e) será diminuída.

4 curtidas

@Capezotte, essa última solução que você trouxe, apesar do quão claro isso poderia quebrar as coisas e dos problemas que você mesmo já citou, realmente achei muito legal! Você pensou nisso sozinho?

Essa função é algo que está implementado built-in no core do Bash?

Como poderíamos fazer nossa própria implementação desse recurso em um shell que não possui isso por default? Não sei se isso é possível… talvez teríamos que mudar o funcionamento do próprio shell para isso.

Sim, está documentado no man bash.

Não tem. command_not_found_handle é uma “cortesia” do Bash, pelo padrão POSIX é somente para escrever uma mensagem de erro e considerar código 127, nada mais, nada menos.

1 curtida

Este tópico foi fechado automaticamente 3 dias depois da última resposta. Novas respostas não são mais permitidas.