I wish to give a solution, primarily based on grg’s reply above, on learn how to take all of the damaged symlinks discovered and remodel them into shell-reusable type, portably in bash and zsh.
I additionally wish to point out, the 2 following equivalances, they may operate the identical:
discover ... ! -exec check -e {} ;
means if the pathname (resolving symlinks) exists, do not discover it. “!” is used right here by “discover”. Can even substitute “-not” instead of “!”.discover ... -exec check ! -e {} ;
means if the pathname (resolving symlinks) does not exist, discover it. “!” is used right here by “check”. I’ll use this within the following instance.
Instance to (1) retailer, (2) print out, and (3) depend the damaged symlinks
pathnames=()
whereas IFS= learn -r -d $' ' pathname; do
pathnames+=( "$pathname" )
performed < <(discover . -type l -exec check ! -e {} ; -print0)
for (( i=0; i<${#pathnames[@]}; i++ )); do
printf "%qn" "${pathnames[@]:"$i":1}"
performed
printf "nBroken symlinks discovered: %sn" "${#pathnames[@]}"
pathnames
is an array to retailer the pathnames discovered, on this case damaged symlinks.discover . -type l -exec check ! -e {} ;
means search in and beneath present listing for damaged symlinks.-type l
finds symlinks andcheck ! -e
exams if the symlink-resolved pathname doesn’t exist.-print0
means delimit the pathnames discovered fromdiscover
utilizing NUL bytes, and print.< <(...)
means course of substitution, in bash/zsh.whereas ... learn
means runlearn
till it encounters end-of-file or experiences an error.IFS=
means do not truncate whitespace at finish/begin of pathname.-r
means do not enable backslashes to flee characters; don’t interpret backslashes.-d $' '
, or-d ''
, means learn in enter delimited by NUL bytes.printf "%qn"
leverages bash’s/zsh’s builtinprintf
to print out pathnames in shell-reusable type."${pathnames[@]:"$i":1}"
makes use of 0-indexed array indexing, transportable array indexing in bash/zsh.
Extra data on the whereas ... learn
loop: https://mywiki.wooledge.org/BashFAQ/001
Pattern setup
Create some damaged symlinks and damaged listing symlinks with some newlines and carriage returns:
ln -s nofile 'damaged symlink'
ln -s nofile $'damaged symlinknwithnnewlines'
ln -s nofile $'damaged symlink withr carriage return'
mkdir tempdir
ln -s tempdir 'damaged dir symlink'
ln -s tempdir $'damaged r dir n_symlink'
sleep 1; rm -d tempdir
sleep 1
is used for Finder to catch up displaying symlink-folder icons for the 2 damaged symlink directories.
Output in zsh, after which in bash
./damaged symlink
./damaged symlink with$'r' carriage return
./damaged $'r' dir $'n'_symlink
./damaged dir symlink
./damaged symlink$'n'with$'n'newlines
Damaged symlinks discovered: 5
./damaged symlink
$'./damaged symlink withr carriage return'
$'./damaged r dir n_symlink'
./damaged dir symlink
$'./damaged symlinknwithnnewlines'
Damaged symlinks discovered: 5