Вы можете использовать wait -n
, чтобы дождаться выхода дочернего элемента, а затем проверить каждый дочерний элемент, если он все еще работает, с помощью kill -0
, чтобы увидеть, какой из них только что вышел. , например:
for f in 15 10 15; do sleep $f & PIDS+="$! " ; done ; wait -n ; for f in $PIDS; do if ! kill -0 $f 2> /dev/null ; then echo $f; fi;
ожидание -n
возвращает только статус выхода дочернего элемента, а не то, какой PID
он был.
git diff $sha1..$sha1^
создает патч, который отменяет коммит $sha1
(в нем перечислены различия между этим коммитом и его родителем). Если указан $file
, этот патч ограничивается изменениями, внесенными в $file
в данной фиксации.
Этот патч затем загружается в patch -p1
, который удаляет поддельные имена каталогов, используемые git
(a/
и b/
) и попытаться применить исправление к любым файлам, перечисленным в исправлении (т.е. , $file
, если он был назван и изменен в данной фиксации, или ко всем файлы, измененные в данной фиксации, включая файлы в подкаталогах). Если файлы, присутствующие в текущем каталоге и его подкаталогах, существенно отличаются (или, по расширению, отсутствуют), patch
не сможет применить патч.
Это стало возможным благодаря тому, что патчи в унифицированном формате, создаваемые git diff
(и diff -u
), включают имена исправляемых файлов и контекст для патча. Вот пример (не из git
, но он показывает идею):
diff -ur cli-common-0.9+nmu1.orig/policy-remove cli-common-0.9+nmu1/policy-remove
--- cli-common-0.9+nmu1.orig/policy-remove 2015-02-25 21:34:08.000000000 +0100
+++ cli-common-0.9+nmu1/policy-remove 2017-04-08 20:47:09.029065259 +0200
@@ -11,4 +11,4 @@
#echo "Removing GAC policy file ($POLICY) from available GACs"
/usr/share/cli-common/gac-package-remove $POLICY > /dev/null
-rm /usr/share/cli-common/packages.d/$POLICY.installcligac
+rm -f /usr/share/cli-common/packages.d/$POLICY.installcligac
Этот патч говорит, что он модифицирует файл с именем cli-common-0.9+nmu1.orig/policy-remove
, чтобы создать файл с именем cli-common-0.9+nmu1/policy-remove
. Само изменение начинается со строки 11 и занимает 4 строки, включая контекст (это @@ -11,4
); в мишени измененные строки находятся в той же позиции (+11,4 @@
).Над изменением есть три строки контекста, затем само изменение, удаление строки, начинающейся с rm
, и добавление строки, начинающейся с rm -f
. Когда patch
применяет это, он будет искать файл с соответствующим именем (после удаления компонентов пути, если это указано с опцией -p
), и сравнивать контекст в файле с пластырь; изменение будет применено только в том случае, если контекст совпадает (в пределах нескольких строк, в зависимости от опций фаззинга).
Весь смысл этого скрипта в том, чтобы попытаться отменить изменения, сделанные в одном файле в данном коммите (отсюда и его название). Возможно это или нет, зависит от изменений, внесенных в файл после этой фиксации; но это часто весьма полезно на практике. (Чтобы отменить полную фиксацию, вы должны вместо этого использовать git revert
.)