디렉토리에 있는 모든 직접 심볼릭 링크, 즉 심볼릭 링크가 아닌 다른 파일을 가리키는 심볼릭 링크를 모두 나열해야 합니다.
나는 이것을 시도한다:
for i in $(ls -1A); do
first_type=$(ls -l $i | cut -b 1)
if [ $first_type == 'l' ]
then
next=$(ls -l $i | awk '{print $NF}')
next_type=$(ls -l $next | cut -b 1)
if [ $next_type != 'l' ]
then
#Some code
fi
fi
done
그러나 이 경우 스크립트는 이름에 공백/탭/줄 바꿈이 있는 파일(파일 이름의 시작과 끝 모두)을 건너뜁니다. 이 문제를 해결할 방법이 있나요?
저는 솔라리스 10에서 작업하고 있습니다. readlink
또는 명령이 없습니다 stat
. 이것find
명령은 그렇지 않습니다 -printf
.
답변1
이 작업을 수행할 수 있는 Perl 코드 조각을 제공할 수 있습니다.
#!/usr/bin/perl
#
foreach my $i (@ARGV) {
# If it is a symlink then...
-l $i and do {
# First indirection; ensure that it exists and is not a link
my $j = readlink($i);
print "$i\n" if -e $j and ! -l $j
}
}
다른 이름으로 저장해서 /usr/local/bin/if-link
실행 가능하게( chmod a+x /usr/local/bin/if-link
) 하면 이렇게 사용이 가능합니다.
/usr/local/bin/if-link * .*
다른 스크립트에 통합하려면 한 줄의 코드로 사용할 수 있습니다.
perl -e 'foreach my $i (@ARGV) { -l $i && do { my $j = readlink($i); print "$i\n" if -e $j and ! -l $j } }' * .*
답변2
Perl의 솔루션을 사용하는 대신 readlink 시스템 호출을 사용하여 내 자신의 미니 버전의 readlink를 구현해 보기로 결정했습니다. 이 유틸리티의 소스 코드는 매우 간단하며 다음과 같습니다.
ret_length = readlink( argv[1], buffer, buffer_size );
if( ret_length >= 0 ) {
buffer[ ret_length ] = '\0';
printf( "%s\n", buffer );
return 0;
} else {
return errno;
}
bash 스크립트(./xrl은 유틸리티 이름입니다. 줄 바꿈이 포함된 파일 이름은 지원되지 않습니다):
USAGE="Usage: chl_xrl filename"
OLDIFS=$IFS
IFS=$'\n'
if [[ $# != 1 ]]
then
echo $USAGE
exit 1
fi
ls -1Au | while read -r pos; do
if [[ $(./xrl "$pos") == $1 ]]
then
echo "$pos"
fi
done
IFS=$OLDIFS
exit 0
개선 사항 - 스크립트는 파일 이름을 인수로 사용하고 직접 링크를 찾지만 디렉터리의 모든 파일을 찾지는 않습니다.