Passando uma variável para um script bash que usa 'EOF' e considera a variável um literal [fechado]

9

Neste script, acabo com "$ 1" sendo salvo no arquivo / test.

#!/bin/bash
cat > /test << 'EOF'
$1
EOF

a verdade é .. eu preciso manter

'EOF'

como 'EOF' porque meu argumento (US $ 1) contém cifrões.

mas preciso que esse argumento seja salvo em vez de US $ 1

user72685
fonte
1
'porque meu argumento ( $1) contém cifrões.' Não se for o primeiro parâmetro da linha de comandos. A substituição foi realizada antes que seu script fosse executado. Você tem que escapar na linha de comando.
Goldilocks
Você fez várias perguntas relacionadas a essa tarefa que está realizando e a progressão das perguntas mostra que você realmente não entende o que está acontecendo e provavelmente não está escolhendo a abordagem mais fácil. É difícil ajudá-lo sem saber o que você está tentando fazer, por isso recomendo que faça uma pergunta em que explique claramente sua tarefa geral e não restrinja as respostas para usar uma ferramenta específica. Por exemplo, não diga "Desejo usar cate manter cifrões", mas "Quero modificar o item httpd.confpara alterar <alguma configuração> desta <desta maneira>".
Gilles 'SO- stop be evil'
@ Gilles, finalmente decidi escrever em um arquivo diferente via python e depois usar um script bash para gravar esse arquivo no arquivo original que foi editado. esse processo é muito mais fácil. Você pode usar o seguinte comando: cat / temp_file> $ 1
user72685
@ Gilles, a razão pela qual minhas perguntas não fazem sentido é porque a maneira como os scripts do bash lidam com as variáveis ​​passadas para eles. há muitas coisas que precisam ser evitadas e ainda não há um recurso para codificar e decodificar em tempo real.
user72685
@Gilles, a única coisa que fez sentido para mim um pouco foi a base64, mas por que é necessário codificar suas coisas para passar para um script bash .. escapando das coisas e tentando reconstruir as coisas dentro do script bash? todas as três barras para escapar de uma crase e etc .. parece-me como um código inferno
user72685

Respostas:

15

Dando seguimento a sua pergunta anterior , parece que você quer tanto um texto não-interpretada e algum texto interpretado entrar em um arquivo. Nesse caso, use dois cats diferentes echo:

cat > /test <<'EOF'
some uninterpreted text $(pwd)
not substituted: $1
EOF
cat >> /test <<EOF
but this will substitute: $1
EOF

Há algumas coisas acontecendo aqui: primeiro, a sintaxe do heredoc<< . Se você incluir aspas nessa sequência terminadora, como na primeira acima, todo o heredoc não será interpretado - sem parâmetros e sem substituições. Se você não usar aspas, como no segundo cat acima, variáveis ​​como $1serão substituídas por seus valores e substituições de comandos serão incluídas no texto. Você escolhe entre citar a sequência "EOF" ou não, com base em se deseja ou não substituições.

Para colocar os dois cats no mesmo arquivo, estamos usando o >> redirecionamento para o segundo (e mais tarde) redirecionamentos: isso significa anexar ao arquivo. Para o primeiro, usamos um único >para limpar o arquivo e começar do zero.

Observe que, mesmo quando as variáveis ​​são substituídas , quaisquer cifrões adicionais no valor dessa variável não são re-substituídos:

foo='$bar'
bar=hello
cat <<EOF
$foo
EOF

irá produzir:

$bar

sem substituir $baro valor de.

No entanto, se você estiver fornecendo um "$" no argumento para todo esse script, precisará escapá-lo na linha de comando ou incluir tudo entre aspas simples. Como alternativa, a substituição de comandos , como em sua outra pergunta, permite inserir diretamente o conteúdo de um arquivo inteiro, incluindo quaisquer cifrões no conteúdo do arquivo. Certifique-se de citar a cadeia de substituição aqui:

oo.sh "$(cat myfile)"

obterá o corpo de myfilecomo $1e pode então catou echocomo necessário. As mesmas limitações da minha resposta são aplicáveis: há um limite para quanto tempo os argumentos da linha de comando podem durar e se o seu arquivo pode demorar mais do que isso, você deve encontrar outra abordagem. Você pode descobrir qual é o limite no seu sistema comgetconf ARG_MAX

Michael Homer
fonte
1

Parece que você simplesmente deseja exibir a única variável no arquivo. Nesse caso, isso funcionará:

echo $1 >/test

Observe que /testestá no diretório raiz, para o qual os usuários comuns geralmente não têm permissão de gravação.

EDIT: Lembre-se de que é necessário citar a seqüência de caracteres que contém o sinal de dólar na linha de comando . É aí que a substituição ocorre, e o script não pode fazer nada a respeito depois do fato.

Tom Zych
fonte
Eu acho que você tem a resposta correta agora. +1
goldilocks
A resposta do @ MichaelHomer é muito mais completa e inclui informações úteis sobre os documentos aqui que eu havia esquecido. Sua resposta deve ser aceita (a menos que alguém poste uma ainda melhor, é claro).
precisa saber é o seguinte