Indlejrede enkelte og dobbelt apostroffer i bash-scripts
Det har altid voldt mig enormt besvær at blande enkelte og dobbelt apostroffer i scripts.
Tag for eksempel denne som sender en mail hvis der er mindre end 80% ledig plads:
Den sender blot en enkelt linje i mailen, fx :
Men hvis jeg vil have en hel sætning puttet ind så virker det ikke:
Her står der altså There is only $5 percent left on the server: $0 i stedet for bare $0
I mail-linjen er det lykkedes mig at indsætte en sætning ved at escape dobbelt-apostrofferne men det går ikke her.
Hvad er der galt, og hvordan styrer man i det hele taget disse apostrofblandinger?
Tag for eksempel denne som sender en mail hvis der er mindre end 80% ledig plads:
df -h | awk --re-interval 'BEGIN { FS = " " } /[0-9]{1,2}%/ {if(strtonum($5)>=80) {system("echo "$0" | mail -s \"SERVER IS RUNNING LOW ON SPACE\" my@email.dk")}}'
Den sender blot en enkelt linje i mailen, fx :
/dev/sda7 9.2G 3.4G 5.4G 90% /var
og det styres af awk-variablen $0.Men hvis jeg vil have en hel sætning puttet ind så virker det ikke:
df -h | awk --re-interval 'BEGIN { FS = " " } /[0-9]{1,2}%/ {if(strtonum($5)>=80) {system("echo "There is only $5 percent left on the server: $0" | mail -s \"SERVER IS RUNNING LOW ON SPACE\" my@email.dk")}}'
Her står der altså There is only $5 percent left on the server: $0 i stedet for bare $0
I mail-linjen er det lykkedes mig at indsætte en sætning ved at escape dobbelt-apostrofferne men det går ikke her.
Hvad er der galt, og hvordan styrer man i det hele taget disse apostrofblandinger?
Kommentarer5
Blot et forslag. Jeg har
df -h | awk --re-interval 'BEGIN { FS = " " } /[0-9]{1,2}%/ {if(strtonum($5)>=80) {print "There is only", $5, "percent left on the server:", $0 }}' | mail -s "SERVER IS RUNNING LOW ON SPACE" my@email.dk
Se mere i The AWK manual: http://people.cs.uu.nl/piet/docs/nawk/nawk_toc.html
Ligesom mich..
Anyway, kan det virkelig passe at det ikke virker at escape de anførselstegn omkring strengen?:
df -h | awk --re-interval 'BEGIN { FS = " " } /[0-9]{1,2}%/ {if(strtonum($5)>=80) {system("echo \"There is only $5 percent left on the server: $0\" | mail -s \"SERVER IS RUNNING LOW ON SPACE\" my@email.dk")}}'
Alternativt, så drop dem helt - det kan echo godt håndtere:
df -h | awk --re-interval 'BEGIN { FS = " " } /[0-9]{1,2}%/ {if(strtonum($5)>=80) {system("echo There is only $5 percent left on the server: $0 | mail -s \"SERVER IS RUNNING LOW ON SPACE\" my@email.dk")}}'
(begge dele er utestet herfra)
Sådan generelt kender jeg godt det med flere hierarkier i strengen og de problemer, det giver. Det ender nogengange i obskure/ulæselige ting med dobbelt-escapes osv. Ofte er det pænere at dele tingene op i stedet for at insistere på at fyre en one-liner af (selvom fristelsen er stor:)).
#1: Dette forslag virker
#2: Hvad enten man escaper apostrofferne eller helt undlader dem, bliver den resulterende tekst i mailen blot: There is only percent left on the server: sh
Tallet mangler, og hvor sh kommer fra, kan jeg ikke helt greje.
#2: Hvad enten man escaper
Det er jo tydeligvis fordi det er shell'en, der fortolker variablerne og IKKE awk. ($0 i en shell giver shell'ens navn - i dette tilfælde "sh").
Nu har du jo løst opgaven, men for forståelsens skyld kan du jo nok løse det ved at hive variablerne udenfor strengen og istedet lade awk fortolke dem og append'e dem til den resulterende streng. Mon ikke flg. gør jobbet:
df -h | awk --re-interval 'BEGIN { FS = " " } /[0-9]{1,2}%/ {if(strtonum($5)>=80) {system("echo \"There is only " $5 " percent left on the server: " $0 " \" | mail -s \"SERVER IS RUNNING LOW ON SPACE\" my@email.dk")}}'
:-)