Mam funkcję bash, która przyjmuje plik jako parametr, sprawdza, czy plik istnieje, a następnie zapisuje w pliku wszystko, co wychodzi ze standardowego wejścia. Naiwne rozwiązanie działa dobrze dla tekstu, ale mam problemy z dowolnymi danymi binarnymi.
echo -n '' >| "$file" #Truncate the file
while read lines
do # Is there a better way to do this? I would like one...
echo $lines >> "$file"
done
> $file
. Działa to tylko jako pierwsza rzecz, która szuka stdin w skrypcie powłoki nadrzędnej. Zasadniczo cały kod Davida można sprowadzić do jednego znaku, ale myślę, żecat -
jest bardziej elegancki i mniej kłopotliwy, ponieważ jest zrozumiały na pierwszy rzut oka.cat
łączę ze sobą cztery lub pięć s, aby wkurzyć fanatyków UUOCcat
tylko dlatego, że ludzie, którzy nalegają na ich użycie, muszą koniecznie ćwiczyć gimnastykę, aby przeczytać kod. Nazwane potoki są również dobrym celem.Aby odczytać plik tekstowy dosłownie, nie używaj zwykłego
read
, który przetwarza dane wyjściowe na dwa sposoby:read
interpretuje\
jako znak ucieczki; użyj,read -r
aby to wyłączyć.read
dzieli się na słowa na znaki w$IFS
; ustawIFS
na pusty ciąg, aby to wyłączyć.Zwykle idiomem przetwarzającym plik tekstowy wiersz po wierszu jest
Aby uzyskać wyjaśnienie tego idiomu, zobacz Dlaczego jest
while IFS= read
używany tak często zamiastIFS=; while read..
? .Aby napisać ciąg dosłownie, nie używaj zwykłego
echo
, który przetwarza ciąg na dwa sposoby:echo
przetwarza odwrotne ukośniki. (W przypadku bash zależy to od ustawieniaxpg_echo
opcji).-n
Lub-e
(dokładny zestaw zależy od powłoki).Przenośnym sposobem drukowania łańcucha jest dosłownie
printf
. (Nie ma lepszego sposobu na bash, chyba że wiesz, że twoje wejście nie wygląda jak opcjaecho
.) Użyj pierwszego formularza, aby wydrukować dokładny ciąg, a drugiego formularza, jeśli chcesz dodać nowy wiersz.Jest to odpowiednie tylko do przetwarzania tekstu , ponieważ:
Nie można przetwarzać danych binarnych w powłoce, ale współczesne wersje narzędzi na większości unikatów radzą sobie z dowolnymi danymi. Aby przekazać wszystkie dane wejściowe do wyniku, użyj
cat
. Posiadanie stycznejecho -n ''
jest skomplikowanym i nieprzenośnym sposobem na nic nie robienie;echo -n
byłby równie dobry (lub nie w zależności od powłoki) i:
jest prostszy i w pełni przenośny.lub prościej
W skrypcie zwykle nie trzeba go używać,
>|
ponieważnoclobber
domyślnie jest wyłączony.źródło
To zrobi dokładnie to, co chcesz:
Zwróć jednak uwagę na użycie pamięci. Odczytuje to dane wejściowe w sposób rozdzielany zerami.
Jeśli na wejściu nie ma bajtów
\0
zerowych, bash najpierw będzie musiał odczytać całą zawartość danych wejściowych do pamięci, a następnie wyprowadzić ją.Jeśli chodzi o krok obcinania:
znacznie prostszym i równoważnym jest:
źródło