Как автоматически найти и сообщить о неработающих символических ссылках?

9

Как аккуратные системные администраторы, нам нравится следить за тем, чтобы мелочи были так же хорошо покрыты, как и большие (когда позволяет время). Одна из этих вещей - обеспечение того, чтобы в наших системах не было битых символических ссылок.

Почему эти маленькие болтуны являются проблемой? Поскольку они заставляют вас думать, что файлы есть, когда их нет, они могут указывать на что-то более раздражающее, и потому что (маленькая) часть OCD меня сходит с ума от всех этих предупреждений при выполнении определенных команд (например grep -r).

Итак, как поступить с обнаружением (и сообщением по электронной почте или с помощью системы мониторинга) неработающих ссылок в тех частях системы, за которые отвечает администратор (нет смысла говорить мне, что ~jbloggsу них куча неработающих символических ссылок, это его проблема )?

ombble
источник

Ответы:

7

Проблема -Lзаключается в том, что побочным эффектом является расширение поиска в подкаталогах, являющихся целями symlinks, которые могут не ожидаться или не желаться.

С GNU findutilsверсией find:

<!-- language: bash -->
find /path/to/search -xtype l

кроме того, что не находит циклические символические ссылки.

-execdir в другом ответе он не так переносим, ​​поэтому переходим к переносимому решению, которое находит неработающие символические ссылки, включая циклические ссылки:

<!-- language: bash -->
find /path/to/search -type l -exec test ! -e {} \; -print

Смотрите этот вопрос , или ynform.org для дальнейшего обсуждения. Также см. Документацию findutils для деталей. Ссылка ynform.org также представляет метод для обнаружения только циклических ссылок.

pooryorick
источник
5

Много способов снять шкуру с кошки

Это вполне переносимо (-L это требование posix)

find -L /path/you/care/about -type l 2>/dev/null | mail -s "Broken symlinks detected" womble@example.com

Вы не определили битые, вышеприведенные будут отправлять вам битые ссылки, которые не имеют цели в той части файловой системы, которая вас интересует. Он также сообщает о циклах файловой системы stderr и проблемах с символическим соединением и т. Д. Если вы тоже о них заботитесь, перенаправьте stderr на вашу почту

find -L /path/you/care/about -type l 2>&1 | mail ...

Если ваша находка поддерживает, это -readableполезно и быстро

find /path/you/care/about -type l ! -readable | mail ...

Вышесказанное включает в себя ссылки со слишком многими уровнями проблем символьных ссылок в его выводе, но не в циклах файловой системы.

Если части файловой системы, о которых вы заботитесь, имеют разные пути,

find /path/you/care/about /another/path ...
иан
источник
find -Lпроблематично для этого варианта использования. См .: unix.stackexchange.com/a/38691/6860
sampablokuper,
1

Я дам вам ответ по Linux, и вы можете при необходимости настроить его под свой Unix:

find . -type l ! -execdir test -e {} \; -print >> broken_symlinks.txt; mutt -s "Broken symlinks" womble@example.com < broken_symlinks.txt; rm -f broken_symlinks.txt

Второй вариант - ls -LR | grep 'cannot access'или некоторые изменения из команды поиска выше.

Редактировать:

Да, это даже лучше find . -type l ! -execdir test -e {} \; -print | mail -s "Broken symlinks" womble@example.com

GRS
источник
1
Почему бы не избавиться broken_symlinks.txtцеликом и просто использовать трубу? И использовать mailвместо muttотправки электронной почты?
Уомбл
0

Это хороший способ сделать это с помощью GNU find:

find <root_dir_of_find> -follow -lname '*' | mail sysadmin -s 'Broken symlink report'

Причина, по которой это работает, заключается в том, что -lnameс -follow(или -L) «... этот тест возвращает false, если символическая ссылка не сломана», согласно странице поиска man.

Вероятно, было бы целесообразно запустить такой тип сканирования диска, когда сервер не используется интенсивно. Может быть полезно использовать niceи / или ionice(см. Этот блог для хорошего описания ionice ), чтобы уменьшить нагрузку на сервер во время выполнения этой задачи.

rorycl
источник
0

Fedora и Ubuntu предоставляют symlinksутилиту. Утилита является собственным исполняемым файлом elf, а не сценарием оболочки оболочки. Утилита была предустановлена ​​на Fedora. Вам может понадобиться установить утилиту в Ubuntu.

С помощью symlinksутилиты вы можете проверить наличие оборванных ссылок с помощью следующей команды.

sudo symlinks -r /usr | grep dangling

Если цели висящих ссылок можно удалить, выполните следующее, чтобы удалить их.

sudo symlinks -r -d /usr

Вот пример вывода на сервер Fedora 31. debian-logo.pngИ ubuntu-logo.pngправильны.

$ sudo symlinks -r /usr | grep dangling
dangling: /usr/lib/.build-id/0a/21c737b7a56e803b12724b2bc4a8d27654ee0e -> ../../../../usr/lib64/perl5/auto/Cwd/Cwd.so
dangling: /usr/lib/.build-id/0c/352d0ca7513dad8eb098d3ad0684379a835aed -> ../../../../usr/lib64/perl5/auto/Unicode/Collate/Collate.so
dangling: /usr/lib/.build-id/1b/99d9d65010cdcc2193b873e7e825e70e23422b -> ../../../../usr/sbin/quota_nld
dangling: /usr/lib/.build-id/1c/c667de4368e4d621257070a451684c373f9952 -> ../../../../usr/sbin/rpc.rquotad
dangling: /usr/lib/.build-id/24/cfecf40f5fca30662589eb016da08a28767697 -> ../../../../usr/lib64/perl5/auto/DB_File/DB_File.so
dangling: /usr/lib/.build-id/25/42192b89d9eaf9c9782b0c22f91ee6440482cd -> ../../../../usr/lib64/dovecot/lib95_imap_filter_sieve_plugin.so
dangling: /usr/lib/.build-id/2a/a949ebff931bc3732fc396a0f2b294bb9e854b -> ../../../../usr/lib64/perl5/auto/Digest/MD5/MD5.so
dangling: /usr/lib/.build-id/34/2a46c23513258e09e87d6808b784a8b6491ff8 -> ../../../../usr/lib64/perl5/auto/Storable/Storable.so
dangling: /usr/lib/.build-id/43/e0a6db8e2b4f4aeb8f5ebb69f3cc716fc5d1cd -> ../../../../usr/lib64/perl5/auto/threads/shared/shared.so
dangling: /usr/lib/.build-id/4a/661475701d2cdcfb7d085c3e6f9bd05485d207 -> ../../../../usr/bin/coreutils.single
dangling: /usr/lib/.build-id/65/46b22b19cdfee2dfab7754d8d7ea316342151b -> ../../../../usr/lib64/perl5/auto/Compress/Raw/Zlib/Zlib.so
dangling: /usr/lib/.build-id/73/60dbe43c8b6c4a666a3bd0dc75e16a679bb784 -> ../../../../usr/lib64/libncurses++.so.6.1
dangling: /usr/lib/.build-id/7a/26a4df12398dbb4130f04a1c367a4dcc7d442b -> ../../../../usr/lib64/perl5/auto/Unicode/Normalize/Normalize.so
dangling: /usr/lib/.build-id/7f/fd3bbd111b6654bfd1b243704efa96ec2d4863 -> ../../../../usr/lib64/perl5/auto/Encode/EBCDIC/EBCDIC.so
dangling: /usr/lib/.build-id/83/2c8a2df088752fdcc9a9551ffce7b3176a4d49 -> ../../../../usr/lib64/perl5/auto/Compress/Raw/Bzip2/Bzip2.so
dangling: /usr/lib/.build-id/8b/65c6430553b93525c53d5cc2ba8fcf4ff3aaee -> ../../../../usr/lib64/perl5/auto/MIME/Base64/Base64.so
dangling: /usr/lib/.build-id/8d/c5a840771ecedd3469ee2f46d069a2eda43bf4 -> ../../../../usr/lib64/perl5/auto/Sys/Syslog/Syslog.so
dangling: /usr/lib/.build-id/91/5242c5632706f91d83e37781b0f9f3fea7095e -> ../../../../usr/lib64/perl5/auto/Encode/JP/JP.so
dangling: /usr/lib/.build-id/ce/88cf936cb7a769cb86fc5a6573e9eb1dd34f11 -> ../../../../usr/sbin/warnquota
dangling: /usr/lib/.build-id/cf/4163f54ccf50ecdf167458d9c191340923e397 -> ../../../../usr/lib64/dovecot/lib90_sieve_plugin.so
dangling: /usr/lib/.build-id/db/462bcd4628914e304d29efdb91c9ef4c8a429c -> ../../../../usr/libexec/dovecot/managesieve
dangling: /usr/lib/.build-id/e4/d5521acb2c6258e041ce769b598b2321b1b759 -> ../../../../usr/lib64/perl5/auto/threads/threads.so
dangling: /usr/lib/.build-id/e8/90366944201ec9b95741c6412384694bdd7512 -> ../../../../usr/lib64/perl5/auto/Data/Dumper/Dumper.so
dangling: /usr/lib/.build-id/e8/249d9630ae331b9202bae7f673e9252fa7253b -> ../../../../usr/sbin/xfs_scrub
dangling: /usr/lib/.build-id/e9/84aa80676f59c7c2509cbff7adc9c75eda481f -> ../../../../usr/lib64/perl5/auto/Encode/TW/TW.so
dangling: /usr/lib/.build-id/eb/adfc3dbd92dd3c040503abd748801b545cc86f -> ../../../../usr/lib64/perl5/auto/Time/Piece/Piece.so
dangling: /usr/lib/.build-id/f1/9dc36368503cdc9fefccc69d5746b63e47908d -> ../../../../usr/libexec/dovecot/managesieve-login
dangling: /usr/lib/.build-id/f4/39e5769bde9d9f8d4544c8f71196ad71ac5f51 -> ../../../../usr/lib64/perl5/auto/Encode/Symbol/Symbol.so
dangling: /usr/lib/.build-id/f5/78cbcea9f6912e60cdddb66910261996ad6141 -> ../../../../usr/lib64/perl5/auto/Encode/Byte/Byte.so
dangling: /usr/lib/.build-id/fc/6f59624f604d702f001f613defb4e076937073 -> ../../../../usr/lib64/perl5/auto/Encode/CN/CN.so
dangling: /usr/lib/.build-id/55/4466f3ba07d8c68e182f4664bea89edc6ca977 -> ../../../../usr/lib64/perl5/auto/Encode/KR/KR.so
dangling: /usr/lib/.build-id/9b/b76a0d6b526ae41ae293e3a380965d6dfbcddb -> ../../../../usr/lib64/perl5/auto/Encode/Encode.so
dangling: /usr/lib/.build-id/e5/9f2cc2a60b3c93cb80f676cb10c33947fff9e1 -> ../../../../usr/lib64/perl5/auto/Filter/Util/Call/Call.so
dangling: /usr/lib/.build-id/1e/0069b4c149b951f05d0a5cc7e422c776fb3e41 -> ../../../../usr/lib64/python3.7/site-packages/gi/_gi_cairo.cpython-37m-x86_64-linux-gnu.so
dangling: /usr/lib/.build-id/36/2656ff4bc2e2d6cd08cd86aa629fecfb37e313 -> ../../../../usr/lib64/perl5/auto/Devel/Peek/Peek.so
dangling: /usr/lib/.build-id/f2/166998840d21e70379abff23a98988717afc3a -> ../../../../usr/lib64/perl5/auto/Digest/SHA/SHA.so
dangling: /usr/lib/.build-id/0d/af1e73e410de195ea920b2384fc69d410ec087 -> ../../../../usr/lib64/perl5/auto/List/Util/Util.so
dangling: /usr/lib/.build-id/d3/46ece08a996170f1e5033ba95d18e2254f54ed -> ../../../../usr/lib64/perl5/auto/Socket/Socket.so
dangling: /usr/lib/.build-id/69/74f3ebcf11fa8d9a19ee54eb50af14be2f42dc -> ../../../../usr/lib64/dovecot/doveadm/lib10_doveadm_sieve_plugin.so
dangling: /usr/lib/.build-id/69/9bacf31170b09a56bb033ede6581984d33c0f7 -> ../../../../usr/lib64/perl5/auto/Time/HiRes/HiRes.so
dangling: /usr/lib/.build-id/96/26d1666cace24a81ee5a77fe9e579258ac342e -> ../../../../usr/lib64/libncurses++w.so.6.1
dangling: /usr/lib/.build-id/5c/c6279fd36f22e35b83b0ac73356dc1a4d76df1 -> ../../../../usr/lib64/perl5/auto/Encode/Unicode/Unicode.so
dangling: /usr/lib/.build-id/9c/ff1249bda228d9278c9c347d0cab4437056810 -> ../../../../usr/lib64/perl5/auto/IPC/SysV/SysV.so
dangling: /usr/lib/.build-id/5e/213a5bf6193f8184edda1f6278c30a9acaf694 -> ../../../../usr/lib64/perl5/auto/Math/BigInt/FastCalc/FastCalc.so
dangling: /usr/lib/.build-id/53/f0c8286103cbd403235e800f53d4b023671916 -> ../../../../usr/lib64/dovecot/lib95_imap_sieve_plugin.so
dangling: /usr/lib/modules/5.3.11-300.fc31.x86_64/build -> /usr/src/kernels/5.3.11-300.fc31.x86_64
dangling: /usr/lib/modules/5.3.11-300.fc31.x86_64/source -> build
dangling: /usr/lib/lsb/install_initd -> ../../../sbin/chkconfig
dangling: /usr/lib/lsb/remove_initd -> ../../../sbin/chkconfig
dangling: /usr/lib/gcc/x86_64-redhat-linux/9/32/libasan.a -> ../../../i686-redhat-linux/9/libasan.a
dangling: /usr/lib/gcc/x86_64-redhat-linux/9/32/libatomic.a -> ../../../i686-redhat-linux/9/libatomic.a
dangling: /usr/lib/gcc/x86_64-redhat-linux/9/32/libgomp.so -> ../../../../libgomp.so.1.0.0
dangling: /usr/lib/gcc/x86_64-redhat-linux/9/32/libitm.a -> ../../../i686-redhat-linux/9/libitm.a
dangling: /usr/lib/gcc/x86_64-redhat-linux/9/32/libquadmath.a -> ../../../i686-redhat-linux/9/libquadmath.a
dangling: /usr/lib/gcc/x86_64-redhat-linux/9/32/libubsan.a -> ../../../i686-redhat-linux/9/libubsan.a
dangling: /usr/lib/gcc/x86_64-redhat-linux/9/32/libstdc++.a -> ../../../i686-redhat-linux/9/libstdc++.a
dangling: /usr/lib/gcc/x86_64-redhat-linux/9/32/libstdc++.so -> ../../../../libstdc++.so.6.0.27
dangling: /usr/lib/gcc/x86_64-redhat-linux/9/32/libstdc++fs.a -> ../../../i686-redhat-linux/9/libstdc++fs.a
dangling: /usr/lib/gcc/x86_64-redhat-linux/9/32/libsupc++.a -> ../../../i686-redhat-linux/9/libsupc++.a
dangling: /usr/share/doc/hunspell/README -> README.md
dangling: /usr/share/man/man7/gnupg2.7.gz -> gnupg.7.gz
dangling: /usr/share/man/man1/ex.1.gz -> vim.1.gz
dangling: /usr/share/man/man1/rview.1.gz -> vim.1.gz
dangling: /usr/share/man/man1/view.1.gz -> vim.1.gz
dangling: /usr/share/cockpit/branding/debian/favicon.ico -> /usr/share/pixmaps/debian-logo.png
dangling: /usr/share/cockpit/branding/debian/logo.png -> /usr/share/pixmaps/debian-logo.png
dangling: /usr/share/cockpit/branding/ubuntu/logo.png -> /usr/share/plymouth/ubuntu-logo.png

источник