Вы просите много с общим ответом, но должно быть возможно сделать это относительно легко в некоторой степени.
Однако bash
имеет по крайней мере два общих механизма, которые могут помочь решить это. Можно установить переменный PROMPT_COMMAND, и это будет выполняться после чего-либо, что Вы выполняете в своей подсказке:
$ PROMPT_COMMAND='echo BOFH says hi!'
BOFH says hi!
$ man man
BOFH says hi!
$
Мы можем использовать это, чтобы сохранить последнюю вводимую команду и затем перечитать ее, таким образом, мы можем сохранить ее в памяти для дальнейшего использования (расширение истории не работает в этом случае):
$ PROMPT_COMMAND='history -a; tail -n1 ~/.bash_history'
PROMPT_COMMAND='history -a; tail -n1 ~/.bash_history'
$ wc < test.sh | grep .
5 11 63
wc < test.sh | grep .
Теперь прибывает логическая часть, которая полностью ваше дело. Давайте использовать просто очень упрощенную логику для предотвращения примера в вопросе. Вещь помнить, тот удар, функции все еще работают там, таким образом, Вы не должны переполнять все на одной строке в единственной переменной.
$ # define the logic check
$ checkSanity() { grep -q "tar *[tf][[:alpha:]]*[tf] " <<< "$@" && echo "be careful, don't delete this"; }
checkSanity() { grep -q "tar *[tf][[:alpha:]]*[tf] " <<< "$@" && echo "be careful, don't delete this"; }
$ # feed it the last command
$ PROMPT_COMMAND='history -a; last=$(tail -n1 ~/.bash_history); checkSanity "$last"'
$ # simple test
$ tar tf test.sh 2>/dev/null
be careful, don't delete this
$ tar xf test.sh 2>/dev/null
$
Конечно, этот подход полезен для предотвращения PEBKAC (особенно, если Вы добавляете sleep 3
в конце), но это не может повредить следующую команду самостоятельно.
Если это действительно, что Вы хотите, захватываете DEBUG
сигнал (например. trap 'echo "I am not deterministic, haha"' DEBUG
), так как это работает заранее. Будьте осторожны с объединением этих двух подходов, так как вывод/действие будет удвоен:
$ df
/.../
$ trap 'tail -n1 ~/.bash_history' DEBUG
df
df
trap 'tail -n1 ~/.bash_history' DEBUG
trap 'tail -n1 ~/.bash_history' DEBUG
Чтобы заставить прерывание повредить команду, необходимо будет включить extdebug
(shopt -s extdebug
). Вы также не должны сохранять и постоянно перечитывать историю, но можете осмотреть $BASH_COMMAND
получить команду, собирающуюся быть выполненным. Затем просто необходимо удостовериться логический возврат средства проверки 1, когда он обнаруживает что-то плохо и 0 иначе.
extdebug
If set, behavior intended for use by debuggers is enabled:
/.../
2. If the command run by the DEBUG trap returns a non-zero value, the next
command is skipped and not executed.
$ checkSanity() { if grep -q "tar *[tf][[:alpha:]]*[tf] " <<< "$1"; then echo "be careful, don't delete this"; return 1; fi; }
$ trap 'checkSanity "$BASH_COMMAND"' DEBUG
$ # simple test
$ tar tf test.sh 2>/dev/null
be careful, don't delete this
$ tar xf test.sh 2>/dev/null
$
Обычно да; rsync
работы путем проверки, существует ли файл, то, если его контрольная сумма не является тем же, то, если части файла имеют ту же контрольную сумму, то передают части, которые имеют другую контрольную сумму (или, отступая к передаче всего файла, если это отсутствует или невозможно найти часть, которая имеет контрольную сумму соответствия с обеих сторон). Таким образом, если у Вас есть файл с тем же именем, но совершенно другое содержание, может быть более дешево передать целый файл вместо различия.
Никакое состояние не сохранено за пределами самого файла, таким образом, не имеет значения, использовали ли Вы rsync
прежде. Содержание в файле является единственной вещью это rsync
использование для решения, что передать.
rsync
может сделать обоих. Если Вы делаете что-то как
rsync -auvz /some/directory remotehost:/destination
затем /some/directory
будет скопирован рекурсивно в remotehost
таким образом, что /destination/directory
будет затем существовать. При выполнении команды снова только изменения будут отправлены.
Если Вы хотите, чтобы файлы в месте назначения были удалены, если они больше не существуют в источнике, добавьте --delete
опция.