# overwrite: copy standard input to output after EOF# version 2. BUG here tooPATH=/bin:/usr/bincase $# in 1) ;;*) echo 'Usage: overwrite file' 1>&2; exit 2esacnew=/tmp/overwr1.$$old=/tmp/overwr2.$$trap 'rm -f $new $old; exit 1' 1 2 15cat >$new # collect the inputcp $1 $old # save original filetrap '' 1 2 15 # we are committed; ignore signalscp $new $1 # overwrite the input filerm -f $new $oldЕсли клавиша DEL будет нажата прежде, чем начнется работа с исходным файлом, то произойдет удаление временных файлов и файл останется один. После сохранения файла сигналы игнорируются, поэтому выполнение последней команды
cpcpoverwriteЗдесь есть некоторая тонкость. Рассмотрим последовательность:
$ sed 's/UNIX/UNIX(TM)g' special | overwrite specialcommand garbled: s/UNIX(TM)g$ ls -l special-rw-rw-rw- 1 you 0 Oct 1 09:02 special #$%@*!$Если в программе, поставляющей входной поток для команды overwrite, произойдет ошибка, то выходной поток будет пустым, и
overwriteВо избежание такого финала можно предложить несколько решений. Команда
overwritetest -2Наилучшее решение заключается в том, чтобы выполнять программу, поставляющую данные, под контролем команды
overwriteoverwriteoverwritetimenicenohup# overwrite: copy standard input to output after EOF# final versionopath=$PATHPATH=/bin:/usr/bincase $# in0|1) echo 'Usage: overwrite file cmd [args]' 1>&2; exit 2esacfile=$1; shiftnew=/tmp/overwr1.$$; old=/tmp/overwr2.$$trap 'rm -f $new $old; exit 1' 1 2 15 # clean up filesif PATH=$opath "[email protected]" >$new # collect inputthen cp $file $old # save original file trap '' 1 2 15 # we are committed; ignore signals cp $new $fileelse echo "overwrite: $1 failed, $file unchanged" 1>&2 exit 1firm -f $new $oldВстроенная команда интерпретатора
shift$2$1$3$2shift$*Заметьте, что значение
PATH/bin/usr/binoverwriteТеперь команда
overwrite$ cat noticeUnix is a Trademark of Bell Laboratories$ overwrite notice sed 's/UNIXUNIX(TM)/g' noticecommand garbled: s/UNIXUNIX(TM)/goverwrite: sed failed, notice unchanged$ cat noticeUNIX is a Trademark of Bell Laboratories$ overwrite notice sed 's/UNIX/UNIX(TM)/g' notice$ cat noticeUNIX(TM) is a Trademark of Bell Laboratories$Типичной задачей является использование редактора
sedoverwriteshell$ cat replace# replace: replace str1 in files with str2, in placePATH=/bin:/usr/bincase $# in0|1|2) echo 'Usage: replace str1 str2 files' 1>&2; exit 1