Substituir o comando no script Bash de outro script

1

Estou tentando configurar um script que buscará as alterações do github, onde um script tem um comando que não é executável no Mac OS X.
O que eu estou querendo é usar sed etc para substituir o comando dentro desse script.

Estes são os comandos:

Comando original (a ser substituído no script):

DIR=$(dirname "$(readlink -f $0)")

Novo comando (quero substituir por):

DIR="$(cd "$(dirname "$0")" && pwd -P)"

O que eu tentei até agora:

StartStopScript="/path/to/script.sh"

DIRnew=""$(cd "$(dirname "$0")" && pwd -P)""

DIRold=""$(dirname "$(readlink -f $0)")""

echo "$StartStopScript" | sed -e 's/"$DIRold"/"$DIRnew"/g'

Isso falha e os comandos parecem ser executados em vez de serem interpretados como uma string.
A figura se resume a citar em sed .

Grato por qualquer ajuda que eu possa conseguir com isso.

    
por Björn Dalberg 14.08.2015 / 12:31

1 resposta

0

OrigScript="/path/to/script.sh"
echo $OrigScript
/path/to/script.sh
#note: no quotes
OrigScript='"/path/to/script.sh"'
echo $OrigScript
"/path/to/script.sh"
#note: with quotes, but not good for filesnames, rather use "$filename" in the command argument


DIRnew='"$(cd "$(dirname "$0")" \&\& pwd -P)"'
echo $DIRnew
"$(cd "$(dirname "$0")" \&\& pwd -P)"
#note: with quotes, escaping & needed for suppressing interpretation by sed

DIRold='"$(dirname "$(readlink -f $0)")"'
echo $DIRold
"$(dirname "$(readlink -f $0)")"
#note: in your question the original DIR=.. did NOT have double quotes,
#I assume a typo

sed -e "s/$DIRold/$DIRnew/g" "$OrigScript"
#note: $OrigScript should NOT have the double quotes in it!
#note: I assume $OrigScript == $StartStopScript

#test:
echo $DIRold | sed "s/$DIRold/$DIRnew/"
"$(cd "$(dirname "$0")" && pwd -P)"
#result includes double quotes!

1) para declarar uma variável com aspas (duplas), você precisa escapar as aspas para ter as aspas na string, use melhor aspas simples para ter certeza que a string dentro é exatamente a string e nenhuma variável é interpretada. Isso também simplifica o uso de & e $() , pois eles não são interpretados pelo shell

2) para echo ing (double) aspas, escape delas

3) por permitir que sed interprete uma variável shell, você DEVE usar aspas duplas em torno do comando sed (com aspas simples, o comando sed 's/$a/$b/' tentará substituir a string real '$ a' pela string '$ b', também esteja ciente do significado especial de $ in sed ), aspas duplas em torno da variável dentro do comando sed não são necessárias, pois sed é para tratar strings com qualquer caractere ( com restrições em relação aos caracteres de comando especiais de sed ).

4) echo "$StartStopScript" | sed -e 's/"$DIRold"/"$DIRnew"/g' irá ecoar a variável $StartStopScript (que eu suponho ser simplesmente o nome do arquivo do script) e tentar substituir as variáveis nessa cadeia (ou seja, o nome do arquivo). Para aplicar sed a um arquivo, use sed 's/a/b/g' file (saída gravada em stout ), para sobrescrever o arquivo, use -i (use com cuidado, ou seja, teste primeiro as substituições corretas)

5) & tem um significado especial em sed , reimprime o padrão inicial (correspondência):

echo ABC | sed 's/A/&12/'
A12BC

Você terá que escapar no padrão de substituição para suprimir a interpretação:

echo ABC | sed 's/A/\&12/'
&12BC

Assim, a variável $DIRnew precisa ter as barras invertidas de escape em sua string.

6) Além disso, sugiro usar um loop if identificando o sistema operacional e adaptar os comandos de acordo. Dessa forma, você só precisa de um script para os dois sistemas operacionais. Ou seja,

if [ OS = Mac ] ; then
    dir=MacDir
else
    dir=LinuxDir
fi
    
por 14.08.2015 / 12:55