Предложенный вопрос не о перезаписи переменных или аргументов, а о том, что как чтение, так и запись в файл одновременно, как правило, плохая идея.
Например, эта команда может выглядеть так, как будто она просто записывает файл в себя, но вместо этого она обрезает его:
cat myfile > myfile # Truncates the file to size 0
Однако, это не проблема в вашей конкретной команде. Он гарантированно работает в POSIX-совместимой оболочке, поскольку порядок операций указывает , что перенаправления произойдут после расширений:
Слова, которые не являются переменными присваиваниями или перенаправлениями, должны быть расширены. Если какие-либо поля остаются после их расширения, первое поле считается именем команды, а остальные поля являются аргументами команды.
Перенаправления должны выполняться, как описано в разделе Перенаправление.
Двойной - однако , он все еще немного хрупок в том смысле, что казалось бы безобидные модификации могут вызвать проблему, например, если вы хотите запустить sed
для результата. Поскольку перенаправление (> "$1"
) и подстановка команд $(cat "$1")
теперь находятся в отдельных командах, определение POSIX больше не спасает вас:
# Command may now randomly result in the original message being deleted
echo "$current_branch $(cat "$1")" | sed -e 's/(c)/©/g' > "$1"
Аналогично, если вы преобразуете его в функцию, он также внезапно перестанет работать:
# Command will now always delete the original message
modify_message() {
echo "$current_branch $(cat "$1")"
}
modify_message "$1" > "$1"
Вы можете избежать этого, записав во временный файл, а затем заменить свой оригинал.
tmp=$(mktemp) || exit
echo "$current_branch $(cat "$1")" > "$tmp"
mv "$tmp" "$1"