Как аккуратные системные администраторы, нам нравится следить за тем, чтобы мелочи были так же хорошо освещены, как и большие (когда позволяет время). Одна из этих вещей - убедиться, что наши системы не содержат битых символических ссылок.
Почему эти маленькие мерзавцы - проблема? Поскольку они заставляют вас думать, что файлы есть, когда их нет, они могут быть признаком чего-то более раздражающего, и потому что (небольшая) часть меня с ОКР сходит с ума от всех этих предупреждений при выполнении определенных команд (например, grep -r
).
Итак, как можно было бы обнаруживать (и сообщать через электронную почту или систему мониторинга) неработающие ссылки в частях системы, за которые отвечает администратор (нет смысла говорить мне, что ~jbloggs
есть куча битых симлинков, в этом его проблема)?
Проблема с -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 также представляет метод обнаружения только циклических ссылок.
Много способов снять шкуру с кошки
Это довольно переносимо (-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 ...
Я дам вам ответ 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.
Редактировать:
Ага, это даже лучше: find . -type l ! -execdir test -e {} \; -print | mail -s "Broken symlinks" womble@example.com
Это хороший способ сделать это с помощью GNU find:
find <root_dir_of_find> -follow -lname '*' | mail sysadmin -s 'Broken symlink report'
Причина, по которой это работает, в том, что -lname
с участием -follow
(или -L) "... этот тест возвращает false, если символическая ссылка не разорвана", согласно поисковой странице руководства.
Вероятно, было бы разумно запустить такое сканирование диска, когда сервер не используется интенсивно. Может быть полезно использовать nice
и / или ionice
(видеть в этом блоге хорошее описание ionice), чтобы снизить нагрузку на сервер при выполнении этой задачи.
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