Comando Shell executado de forma diferente em um terminal e script

2

A seguinte sequência de comandos

ch='echo "b_d" | sed 's/_/\\\\_/''
echo $ch

quando executado em um terminal ou via source , fornece uma saída

b\_d

Quando correu como um scipt

sh script.sh

em que o conteúdo do script é:

#!/bin/bash                                                                                                                                   
ch='echo "b_d" | sed 's/_/\\\\_/''
echo $ch

a saída é

b\_d

A saída do terminal é a preferida. Qual é a solução para usar o script de shell? Também aceito como respostas são idéias de como modificar

ch='echo "b_d" | sed 's/_/\\\\_/''

para sh .

Eu uso o shell bash:

echo $0
bash
    
por Viesturs 25.08.2018 / 11:05

1 resposta

2

sh difere de bash e se comporta de maneira diferente.

Eu acho que sh é realmente dash .

BTW: há um comportamento diferente com este comando se você verificar diferentes shells.

bosh , dash , mksh , zsh bem como ksh no Solaris imprimem uma barra invertida

bash e ksh no Linux imprimem duas barras invertidas.

Olhando para a saída $ shell -x, acredito que uma barra invertida é a saída correta.

Eu não tenho idéia do porquê ksh se comporta dessa maneira no Linux. Pode ser que ele tente imitar o comportamento bash .

Para bash , o comportamento pode ser explicado: o bash tem um echo não-POSIX que não interpreta backshlashes como requerido pelo POSIX.

O POSIX permite o comportamento de bash apenas em pequenos sistemas embarcados e o POSIX requer as chamadas extensões XSI a serem implementadas. Com echo , isso requer seguir totalmente o comportamento de echo , conforme implementado em 1982 por AT & T para SYSv.

Uma nota importante:

Se você tem um script que começa com

#!/bin/bash

e isso é executável ( x bit definido por chmod ), e se você chamar

sh myscript

esse script ainda é executado por /bin/sh , que normalmente é dash no Linux. Portanto, tenha cuidado ao executar seu código.

Existe uma maneira de evitar o seu problema. Altere seu script para usar:

ch='echo "b_d" | sed 's/_/\\\\_/''
printf '%s\n' $ch

Dessa forma, você evita os problemas com echo que foram introduzidos em 1989 com bash . printf ainda não resolve todos os problemas, pois há muitas implementações com bugs, mas os problemas comuns que surgem das barras invertidas nos argumentos não são afetados por printf .

    
por 25.08.2018 / 11:23