ls 명령에 대한 쉘 스크립트는 어디에서 찾을 수 있습니까? [폐쇄]

ls 명령에 대한 쉘 스크립트는 어디에서 찾을 수 있습니까? [폐쇄]

저는 이 명령이 어떻게 작동하는지 이해하려고 노력하고 있으며 파일 시스템의 위치를 ls​​정의하는 쉘 스크립트가 있다고 가정합니다 . ls이게 옳은 거니? 그렇다면 어디서 찾을 수 있나요?

답변1

ls디렉터리의 모든 파일을 사용 opendir()하고 단계별로 실행합니다. readdir()그 중 하나에 대한 추가 정보가 필요하면 를 호출합니다 stat(). 물론 소스 코드를 읽어보세요. 하지만 매우 편리한 단축키는 다음과 같습니다.

# strace ls

의견의 몇 가지 주요 부분은 다음과 같습니다.

디렉토리 항목 가져오기

open(".", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 3
fcntl64(3, F_GETFD)                     = 0x1 (flags FD_CLOEXEC)
getdents64(3, /* 53 entries */, 32768)  = 1744
getdents64(3, /* 0 entries */, 32768)   = 0
close(3)                                = 0

stdout이 문자 장치인지 확인하십시오.

fstat64(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 0), ...}) = 0

표준 입력을 메모리에 매핑합니다. (왜인지는 모르겠지만, 소스코드를 보세요)

mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1,
0) = 0xb73ff000

표준 출력에 디렉토리 항목 쓰기 및 요약

write(1, "bin  Desktop  Documents  Downloa"..., 91bin  Desktop
Documents  Download  Music  Pictures  Public  public_html  Templates
Videos
) = 91
close(1)                                = 0
munmap(0xb73ff000, 4096)                = 0
close(2)                                = 0
exit_group(0)                           = ?

답변2

ls쉘 스크립트가 아니며 file다음 명령을 실행하면 ELF 64비트 LSB 실행 파일임을 알 수 있습니다.

$ type -a ls
ls is aliased to `ls --color=auto'
ls is /usr/bin/ls #<---- now we know the file path of `ls`
ls is /bin/ls
$ 
$ file /usr/bin/ls
/usr/bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=ddf8cdb3f1fd2e8263637b7c8ccea84fbf41ee3c, stripped
$ 

소스 코드는 온라인에서 찾을 수 있습니다.여기.

또는 배포판이 RPM 기반 Linux 배포판+인 경우 다음을 dnf수행할 수 있습니다.

$ rpm -qf /usr/bin/ls
coreutils-8.22-22.fc21.x86_64 #so now we know the package name is coreutils
$ sudo dnf whatprovides /usr/bin/ls #alternative way
Using metadata from Mon May 16 02:39:55 2016 (1 day, 23:03:50 hours old)
coreutils-8.22-22.fc21.x86_64 : A set of basic GNU tools commonly used in shell scripts
Repo        : @System

coreutils-8.22-19.fc21.x86_64 : A set of basic GNU tools commonly used in shell scripts
Repo        : fedora

coreutils-8.22-22.fc21.x86_64 : A set of basic GNU tools commonly used in shell scripts
Repo        : updates

$ 
$ mkdir coreutils #optional
$ cd coreutils #optional
$ sudo dnf download --source coreutils
...
$ rpm2cpio coreutils-8.22-22.fc21.src.rpm |cpio -idmv
...
$ sudo rm coreutils-8.22-22.fc21.src.rpm #optional
$ unp coreutils-8.22.tar.xz
...
$ rm coreutils-8.22.tar.xz #optional
$ cd coreutils-8.22/
$ find . -iname 'ls*'
./lib/lseek.c
./lib/lstat.c
./src/ls.c  #<---- now we know ls.c is here
./src/ls-vdir.c
./src/ls.h
./src/ls-ls.c
./src/ls-dir.c
./man/ls.x
./tests/ls
./tests/misc/ls-misc.pl
./tests/misc/ls-time.sh
./m4/ls-mntd-fs.m4
./m4/lstat.m4
./m4/lseek.m4
$ vi ./src/ls.c

노트:

  1. coreutils-8.22-22.fc21.src.rpm은 내 것이므로 패키지 번호는 다를 수 있습니다.

  2. return "history is a shellbuiltin" 과 같은 일부 명령의 경우 type -a history현재 쉘 소스 코드를 확인해야 합니다. 즉, rpm -qf `readlink -f /proc/$$/exe`(명령으로 현재 쉘 감지는교활한생각보다 이 트릭은 쉘에서는 작동하지 않습니다 fish.)

  3. where historycsh/tcsh 쉘에는 그러한 명령이 없으므로 사용해야 합니다 type. 자세한 내용을 확인하실 수 있습니다여기.

  4. 예를 들어 설치되지 않은 패키지를 포함하는 등 와일드카드를 사용해 보는 것도 좋습니다 repoquery --resolve --archlist=src '*compress*'("*uncompress*"와 같은 명령을 쿼리하는 경우 주의하세요. 이 경우 "*uncompress*"를 시도하면 접두사를 제거해야 합니다). 범위를 좁히기 위한 첫 번째 "un"은 실패했습니다. 위 출력에서는 repoquery중간 부분을 제거해야 합니다.0:및 선택적 접미사.rpm검색 가능한 정확한 이름을 얻으세요http://rpm.pbone.net, 예를 들어 ncompress-0:4.2.4.4-3.fc21.src를 ncompress-4.2.4.4-3.fc21.src.rpm으로 변경합니다.

  5. dnf가 소스 코드를 다운로드할 때 미러 디버깅을 활성화하여 미러 서버가 다운되는 것을 방지할 수 있습니다. 바라보다이것.

[고쳐 쓰다]

당신이 나와 비슷하고 잘못된 저장소로 인해 rpm 오류가 발생한 경우 해결 방법은 다음과 같습니다.

$ sudo dnf config-manager --set-enabled '*' #Enable all repos, at anytime, check with `sudo dnf repolist all`
$ repoquery --resolve --archlist=src '*compress*'                                       
Could not match packages: failure: repodata/repomd.xml from rpmfusion-free-rawhide-source: [Errno 256] No more mirrors to try.
http://free.nchc.org.tw/rpmfusion/free/fedora/development/rawhide/source/SRPMS/repodata/repomd.xml: [Errno 14] HTTP Error 404 - Not Found                               
...
$ repoquery --resolve --archlist=src --enablerepo='*source' --disablerepo='rpmfusion-free-rawhide-source'  '*compress*' #not works too
...
$ sudo yum-config-manager --save --disablerepo=rpmfusion-nonfree-rawhide-source #for unknown reason, it doesn't work
$ sudo dnf config-manager --set-disabled rpmfusion-free-rawhide-source #for unknown reason, it doesn't work
$ grep -rnIH -D skip --color=always rpmfusion-free-rawhide-source /etc/yum.repos.d/
/etc/yum.repos.d/rpmfusion-free-rawhide.repo:17:[rpmfusion-free-rawhide-source]
$ sudo vi /etc/yum.repos.d/rpmfusion-free-rawhide.repo #Edit rpmfusion-free-rawhide-source from enabled=1 to enabled=0
$ repoquery --resolve --archlist=src  '*compress*'#now should works :) repeat the `grep and vi` steps above if got error in other repos, in my case i have to disable rpmfusion-nonfree-rawhide-source too.

추신:[rpmfusion-free-rawhide-source]에서 [rpmfusion-free-rawhide-source]로 제목을 편집합니다.장애를 입히다] 해킹을 통해 --enablerepo='*source' 작업을 수행해야 합니다. 하지만 지금까지는 첫 번째 명령에서 이미 모든 저장소를 활성화했기 때문에 이것이 불필요하다는 것을 알았습니다.

답변3

ls가 C로 작성되었기 때문에 이것이 답인지는 모르겠지만 for 루프를 사용하여 "ls"를 실행하는 쉘 스크립트를 작성할 수 있습니다.

for f in *;do echo $f;finished

일부 정적 쉘에서도 유용합니다 ...

관련 정보