почему «ls * bash *» не показывает файл .bashrc [дубликат]

git diff $sha1..$sha1^ создает патч, который отменяет коммит $sha1 (в нем перечислены различия между этим коммитом и его родителем). Если указан $file, этот патч ограничивается изменениями, внесенными в $file в данной фиксации.

Этот патч затем загружается в patch -p1, который удаляет поддельные имена каталогов, используемые git (a/ и b/ ) и попытаться применить исправление к любым файлам, перечисленным в исправлении (т.е. , $file, если он был назван и изменен в данной фиксации, или ко всем файлы, измененные в данной фиксации, включая файлы в подкаталогах). Если файлы, присутствующие в текущем каталоге и его подкаталогах, существенно отличаются (или, по расширению, отсутствуют), patch не сможет применить патч.

Это стало возможным благодаря тому, что патчи в унифицированном формате, создаваемые git diffdiff -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.)

0
26.03.2016, 10:53
3 ответа

В большинстве оболочек символ "*" не совпадает с начальным "." по историческим причинам (например, файлы, начинающиеся с ".", считаются скрытыми, а "." & ".." относятся к каталогам)

Следовательно ls не будет отображать .bashrc, но ls -a покажет все файлы. Точно так же ls * расширится на все файлы, кроме тех, которые начинаются с "." персонаж.

Измените это поведение с помощью shopt -s dotglob , который сообщает bash, что "*" также должно соответствовать начальному "." символ. После этого ls * также покажет .bashrc.

1
28.01.2020, 02:13

Причина в том, что первая точка - это соглашение для «скрытого файла» и подстановки файлов (это имя для использования * как «любое количество любых символов» и ? как «любой один символ» и несколько других) специально исключает начальную точку, потому что это означает «скрытый файл».

Если вы напишете ls -l. * , вы получите соответствие .bashrc , но вы также будете соответствовать специальным скрытым файлам . и .. , которые являются каталогами, поэтому для отображения скрытых файлов вам понадобится что-то вроде этих строк:

  • ls -ld. *
  • ls -l. [^.] *
  • LS-A | grep bash

ls -A * bash * не покажет вам .bashrc , потому что подстановка файлов выполняется до того, как вступит в силу параметр -A .

Если вы хотите изменить способ подстановки файлов со скрытыми файлами, вы можете выполнить shopt -s dotglob , либо просто в оболочке для тестирования, либо вставьте в свой.bash_profile или .bashrc, чтобы он всегда был эффективным.

1
28.01.2020, 02:13

Опция оболочки dotglob управляет этим:

$ shopt -s dotglob
$ ls *bash*
.bash_history  .bash_logout  .bashrc

Она не включена по умолчанию, вероятно, в качестве меры удобства/безопасности, поскольку большинство конечных пользователей не беспокоятся о dotfiles и могут легко удалить критические файлы домашнего каталога (такие как .config, .ssh) случайно.

8
28.01.2020, 02:13

Теги

Похожие вопросы