Noriu perskaityti failą ir išsaugoti jį kintamajame, tačiau turiu išsaugoti kintamąjį, o ne tik atspausdinti failą. Kaip tai padaryti? Parašiau šį skriptą, bet jis ne visai toks, kokio man reikėjo:
#!/bin/sh
while read LINE
do
echo $LINE
done <$1
echo 11111-----------
echo $LINE
Savo scenarijuje kaip parametrą galiu nurodyti failo pavadinimą, todėl, pavyzdžiui, jei faile yra "aaaa", jis atspausdintų štai ką:
aaaa
11111-----
Bet tai tik išspausdina failą į ekraną, o aš noriu jį įrašyti į kintamąjį! Ar yra paprastas būdas tai padaryti?
Įvairiose platformose mažiausią bendrą vardiklį sh
naudojate:
#!/bin/sh
value=`cat config.txt`
echo "$value"
Naudojant bash
arba zsh
, norint perskaityti visą failą į kintamąjį, nekviečiant cat
:
#!/bin/bash
value=$(<config.txt)
echo "$value"
cat
iškvietimas bash
arba zsh
, norint išsiurbti failą, būtų laikomas Useless Use of Cat.
Atkreipkite dėmesį, kad norint išsaugoti naująsias eilutes, komandos pakeitimo nereikia cituoti.
Dvi svarbios kliūtys
į kurias iki šiol nebuvo atsižvelgta kituose atsakymuose:
Traukiamosios naujos eilutės pašalinimas iš komandos plėtinio
Tai yra problema, susijusi su:
value="$(cat config.txt)"
tipo sprendimams, bet ne skaitymo
tipo sprendimams.
Komandos išplėtimas pašalina baigiamąsias naująsias eilutes:
S="$(printf "a\n")"
printf "$S" | od -tx1
Išeina:
0000000 61
0000001
Tai sugriauna naivųjį skaitymo iš failų metodą:
FILE="$(mktemp)"
printf "a\n\n" > "$FILE"
S="$(<"$FILE")"
printf "$S" | od -tx1
rm "$FILE"
POSIX sprendimo būdas: prie komandos plėtinio pridėti papildomą simbolį ir vėliau jį pašalinti:
S="$(cat $FILE; printf a)"
S="${S%a}"
printf "$S" | od -tx1
Išvestys:
0000000 61 0a 0a
0000003
Beveik POSIX apeinamas sprendimas: ASCII kodavimas. Žr. toliau.
NUL simbolių pašalinimas
Nėra jokio protingo Bash būdo saugoti NUL simbolius kintamuosiuose.
Tai turi įtakos ir plėtojimo, ir skaitymo
sprendimams, ir aš nežinau jokio gero sprendimo, kaip tai apeiti.
Pavyzdys:
printf "a\0b" | od -tx1
S="$(printf "a\0b")"
printf "$S" | od -tx1
Išvestys:
0000000 61 00 62
0000003
0000000 61 62
0000002
Ha, mūsų NUL dingo!
Apėjimo būdai:
ASCII kodavimas. Žr. toliau.
naudoti bash plėtinį $""
:
S=$"a\0b"
printf "$S" | od -tx1
Veikia tik literalams, todėl nenaudinga skaityti iš failų.
Klaidų apėjimas
Kintamajame saugokite uuencode base64 koduotą failo versiją ir prieš kiekvieną naudojimą ją iškoduokite:
FILE="$(mktemp)"
printf "a\0\n" > "$FILE"
S="$(uuencode -m "$FILE" /dev/stdout)"
uudecode -o /dev/stdout <(printf "$S") | od -tx1
rm "$FILE"
Išvestis:
0000000 61 00 0a
0000003
uuencode ir udecode yra POSIX 7, bet jų nėra Ubuntu 12.04 pagal nutylėjimą (sharutils
paketas)... Nematau POSIX 7 alternatyvos bash proceso <()
pakeitimo plėtiniui, išskyrus įrašymą į kitą failą...
Žinoma, tai lėta ir nepatogu, todėl manau, kad tikrasis atsakymas yra toks: nenaudokite Bash, jei įvesties faile gali būti NUL simbolių.