어떻게 우아 하 게 셸 스 크 립 트 를 작성 합 니까?

4983 단어 Linux
Linux shell 의 스 크 립 트 언어 는 매우 재 미 있 고 독특한 프로 그래 밍 언어 라 고 할 수 있 습 니 다. 다음은 제 가 접 한 재 미 있 는 작은 기 교 를 열거 하 겠 습 니 다. 그들 이 프로 그래 밍 에 사용 할 수 있 는 것 은 아니 지만 여러분 의 이해 shell 에 매우 큰 의 미 를 가 집 니 다.
아무것도 하지 않 음: 사칭 (:) 명령
그것 은 별로 쓸모 가 없 는 것 처럼 보이 지만, 이 빈 명령 은 실제로 또 다른 기능 이 있다. 아무것도 하지 않 고 0 상태 코드 로 돌아 가 는 것 이다.이 특성 때문에, 그것 은 사실 만능 명령 으로, 그것 을 이용 하면 매우 번 거 로 운 이상 처 리 를 끝 낼 수 있다.또한 파일 을 초기 화 할 수 있 는 신병 이기 도 합 니 다 (파일 이 존재 하면 내용 을 비 웁 니 다).
: > foo.log 

가짜 삼 목 연산 자
프로그램 을 작성 할 때 세 개의 연산 자 를 사용 하면 프로그램 을 더욱 우아 하 게 할 수 있다.그러나 안 타 깝 게 도 shell 스 크 립 트 에는 세 개의 연산 자가 없다.그러나 우 리 는 작은 수단 을 통 해 위 3 목 연산 자 를 실현 할 수 있다.
#    $foo $bar ,  $baz   0,   $baz   1
[ $foo -ge $bar ] && baz=0 || baz=1

이것 은 나 로 하여 금 Lua 등 스 크 립 트 언어 에서 자주 사용 하 는 프로 그래 밍 기법 을 생각 나 게 한다. 예 를 들 어 함수 의 선택 가능 한 매개 변 수 를 기본 값 으로 설정 할 때 이렇게 쓸 수 있다 a = a or 0;. 또는 한 편의 글 에서 모든 단어 가 나타 나 는 빈도수 CountTable[a] = CountTable[a] and CountTable[a] + 1 or 1 를 통계 할 수 있다. 이런 단락 연산 의 특성 을 이용 하여 매우 우아 한 프로 그래 밍 기법 을 실현 할 수 있 고 세 개의 연산 자 에 만 국한 되 지 않 는 다.
변수 에 기본 값 설정
어떤 인 자 를 인용 할 때 이 인자 가 정의 되 지 않 으 면 빈 문자열 로 처 리 됩 니 다.그러나 실제 프로 그래 밍 에서 우 리 는 항상 다른 기본 값 을 설정 해 야 한다. 그러면 우 리 는 이렇게 할 수 있다.
# $bar    $foo,   $bar     $foo   0
foo=${bar:-0}

그 나 저 나 - 가 아 닌 = 이 라면 $bar 과 함께 할당 0 이다.
# $bar    $foo,   $bar     $foo $bar     0
foo=${bar:=0}

실행 중인 스 크 립 트 파일 이 있 는 디 렉 터 리 의 절대 경 로 를 가 져 옵 니 다.
이것 도 프로 그래 밍 에서 자주 만 나 는 수요 라 고 믿는다.다음 스 크 립 트 666.sh /home/luweirong/Downloads 에 대해 서 는 pwd 를 통 해 이 스 크 립 트 파일 자체 가 있 는 디 렉 터 리 의 절대 경 로 를 얻 으 려 고 합 니 다.
#!/bin/bash
pwd

하지만 /home/luweirong 에서 실행 하면
./Downloads/666.sh

얻 은 결 과 는 다음 과 같다. /home/luweirong 이 방법 은 분명히 불가능 하 다.따라서 대상 자원 에 정확하게 접근 하려 면 절대 경 로 를 사용 해 야 합 니 다. 이 스 크 립 트 파일 이 있 는 디 렉 터 리 의 절대 경 로 를 먼저 가 져 와 야 합 니 다.다음 명령 은 붙 여 넣 기 를 직접 복사 할 수 있 으 며 모든 경우 에 적용 된다.
script_dir_path=$(dirname $(readlink -f $0))

그리고 이 스 크 립 트 파일 의 심 볼 릭 링크 가 실행 된다 면 $script_dir_path 값 은 이 스 크 립 트 파일 (링크 가 아 닌) 이 있 는 디 렉 터 리 의 절대 경로 입 니 다.그러나 하 드 링크 라면 그 값 은 이 링크 파일 이 있 는 디 렉 터 리 의 절대 경로 일 것 입 니 다.그러나 BSD, OSX 등 시스템 에서 readlink 명령 의 운영 체제 가 다 르 기 때문에 coreutils 패키지 안의 greadlink GNU readlink 를 선택 하여 대체 할 수 있다.
script_dir_path=$(dirname $(greadlink -f $0))s

스 크 립 트 가 중 지 될 때 자동 으로 실행 되 는 동작 설정ShellScript 실행 과정 에서 임시 파일 을 자주 생 성하 여 데이터 의 중계 역 으로 이용 한 후에 삭제 합 니 다.파일 생 성 후 미 처 처리 하고 삭제 하지 못 해 프로그램 이 갑자기 종료 되면 쓰레기 파일 이 남아 있다.혹은 더 심각 한 것 은 중요 한 파일 을 수정 하거나 이동 하 였 으 나 수정 하지 못 하고 프로그램 이 종료 되 었 습 니 다.(물론 정상 적 인 종료 상황 에서 도 이 파일 들 을 처리 해 야 한다) 이때 trap 명령 이 반 짝 거 리 며 등장 했다.
trap "
  mv /tmp/swap-file original-file
  rm /tmp/target-file
" 0

위 명령 의 마지막 0 은 프로그램 이 종 료 될 때 프로그램 자체 에 보 내 는 편지 번호 입 니 다.trap 를 잘 사용 하려 면 Linux 의 신호 체 제 를 잘 이해 해 야 한다.프로그램 실행 을 중지 하 는 데 자주 사용 되 는 SIGTERMSIGKILL 등 신 호 를 제외 하고 수 십 가지 다른 신호 가 있어 kill -l 명령 으로 볼 수 있다.
$ kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL
 5) SIGTRAP      6) SIGABRT      7) SIGBUS       8) SIGFPE
 9) SIGKILL     10) SIGUSR1     11) SIGSEGV     12) SIGUSR2
13) SIGPIPE     14) SIGALRM     15) SIGTERM     17) SIGCHLD
18) SIGCONT     19) SIGSTOP     20) SIGTSTP     21) SIGTTIN
22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO
30) SIGPWR      31) SIGSYS      35) SIGRTMIN    36) SIGRTMIN+1
37) SIGRTMIN+2  38) SIGRTMIN+3  39) SIGRTMIN+4  40) SIGRTMIN+5
41) SIGRTMIN+6  42) SIGRTMIN+7  43) SIGRTMIN+8  44) SIGRTMIN+9
45) SIGRTMIN+10 46) SIGRTMIN+11 47) SIGRTMIN+12 48) SIGRTMIN+13
49) SIGRTMIN+14 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8
57) SIGRTMAX-7  58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4
61) SIGRTMAX-3  62) SIGRTMAX-2  63) SIGRTMAX-1  64) SIGRTMAX
0 를 통 해 자발적으로 보 낼 수 없 기 때문에 위 에서 볼 수 없습니다.
임시 파일 만 들 기
위 에서 말 한 바 와 같이 임시 파일 을 만 드 는 것 은 kill 스 크 립 트 를 작성 하 는 과정 에서 매우 흔 하지만, 매번 이 파일 들 을 위해 가능 한 한 충돌 이 없 는 이름 을 생각 하 는 것 은 정말 번거롭다.이때 shell 명령 이 도움 이 될 것 이다.
temp_file=$(mktemp) # /tmp               ,  : /tmp/tmp.C3N9Ng6IaU
temp_dir=$(mktemp -d) # /tmp               ,  : /tmp/tmp.wDOVMXVcio

임시 문서 인 이상 사후 처 리 를 하 는 것 도 잊 지 마 세 요.
#      
temp_file=$(mktemp)
temp_dir=$(mktemp -d)

#        
trap "
rm $temp_file
rm $temp_dir
" 0

좋은 웹페이지 즐겨찾기