'새 형의 리 눅 스 개인 요리' 13 장 shel script 연습 문제 답

리 눅 스 명령 에 대한 느낌 이 별로 없 기 때문에 새 형의 책 을 찾 아 보 았 습 니 다. 며칠 동안 기초 편의 셸 부분 을 보 았 는데 수확 이 많 았 습 니 다. 적어도 리 눅 스 명령 에 대해 느낌 이 있 었 고 앞으로 배 운 지식 도 이론 지식 에 있어 어느 정도 확대 되 었 습 니 다.우선 긴 말 하지 말고 연습 문제 의 답안 을 나 누 어 라.
'새 형의 리 눅 스 개인 요리' 기초 편 P398 연습 문제
(1) 스 크 립 트 를 새로 만 드 십시오. 이 스 크 립 트 를 실행 할 때 이 스 크 립 트 는 현재 신분 (whoami 로) 과 현재 있 는 디 렉 터 리 (pwd 로) 를 표시 할 수 있 습 니 다.
이 문제 의 답안 은 이미 직접 제시 되 었 으 니 바로 대본 에 올 려 라.
#!/bin/bash
# Program:
#       Showing who you are and where you are.
# History:
#       2015/07/26      XPleaf  First release
PATH=$PATH:~/bin
export PATH
echo "the user is '$(whoami)',and you are in '$(pwd)'"

실행 결과:
[root@moban test]# sh sh01.sh 
the user is 'root',and you are in '/root/scripts/test'

(2) 생일 이 며칠 남 았 는 지 계산 할 수 있 는 프로그램 을 스스로 작성 하 세 요.
이 문 제 는 좀 복잡 합 니 다. 문 제 는 어렵 지 않 지만 date 명령 의 운용 이 익숙 해 야 합 니 다. 여기 서 제 가 직접 취 하 는 방법 은:
  • 사용 자 는 19960621 형식의 생일
  • 을 입력 하 십시오.
  • 사용자 의 생일 을 그해 의 (예 를 들 어 올 해 는 2015) 로 전환한다. 20159621
  • 현재 날짜 와 사용자 생일 날짜 (이미 그해 로 전환) 를 모두 초 로 표시
  • 생일 초 까지 = 사용자 생일 날짜 초 수 - 현재 날짜 초 수
  • '생일 초 거리' 를 일수 로 전환
  • 이 일수 의 양 과 음 을 판단 하여 사용자 의 생일 이 지 났 는 지 알 수 있다
  • 스 크 립 트 는 다음 과 같 습 니 다:
    #!/bin/bash
    # Program:
    #       Telling you how many days are there before your birthday.
    # History:
    #       2015/07/26      XPleaf  First release
    PATH=$PATH:~/bin
    export PATH
    
    read -p "Please input your birthday like <19960621> : " bith_input
    
    bith_input_MD=$(echo $bith_input | awk 'BEGIN {FS=""} {print $5$6$7$8}')
    declare -i now_s=`date +%s`
    declare -i bith_s=`date --date="$(date +%Y)$bith_input_MD" +%s`
    declare -i total_s=$(($bith_s-$now_s))
    declare -i total_day=$(($total_s/60/60/24))
    if [ "$total_day" -gt "0" ];then
            echo "There are $total_day day(s) before your bithday."
    elif [ "$total_day" -eq "0" ];then
            echo "Today is your birthday!!!~Happy Birthday to you!"
    else
            echo "Your birthday in this year had gone!"
    fi

    실행 결과:
    [root@moban test]# sh sh02.sh 
    Please input your birthday like <19960621> : 20150730
    There are 3 day(s) before your bithday.

    저 는 이 방법 이 비교적 복잡 하 다 고 생각 합 니 다. 그래서 저 는 아주 간단 한 방법 이 있 을 거 라 고 생각 합 니 다. 아 시 는 분 들 은 저 에 게 알려 주 셔 서 감사합니다.
    (3) 사용자 에 게 숫자 를 입력 하 게 합 니 다. 프로그램 은 1 + 2 + 3... 사용자 가 입력 한 숫자 까지 누적 할 수 있 습 니 다.
    위의 문제 와 마찬가지 로 상호작용 도 한다. 그러나 이 문 제 는 훨씬 간단 하 다. 그렇게 많은 데이터 처리 가 없다. 그리고 C 언어 에서 이런 문 제 를 많이 봤 기 때문에 비교적 간단 한 문제 이다. 바로 스 크 립 트 에 들어간다.
    #!/bin/bash
    # Program:
    #       You input the number, and I caculate 1+2+3+...+the number.
    # History:
    #       2015/07/26
    PATH=$PATH:~/bin
    export PATH
    
    echo "You input the number, and I caculate 1+2+3+...+the number."
    read -p "Please input the number: " nu
    
    for((i=s=0;i<=$nu;i++))
    do
            s=$(($s+$i))
    done
    
    echo "1+2+3+...+$nu ==> $s"

    실행 결과:
    [root@moban test]# sh sh03.sh 
    You input the number, and I caculate 1+2+3+...+the number.
    Please input the number: 100
    1+2+3+...+100 ==> 5050

    (4) 프로그램 을 만 듭 니 다./root/test/logical 이라는 이름 이 존재 하 는 지 확인 하 는 역할 을 합 니 다. 존재 하지 않 으 면 파일 을 만 들 고 touch 로 만 들 고 생 성 이 완료 되면 떠 나 는 역할 을 합 니 다.존재 한다 면 이 이름 이 파일 인지 여 부 를 판단 하고 파일 이 라면 삭제 한 후 디 렉 터 리 를 새로 만 듭 니 다. 파일 이름 은 logical 이 고 나중에 떠 납 니 다.존재 하고 이 이름 이 디 렉 터 리 라면 이 디 렉 터 리 를 삭제 합 니 다!
    제목 은 비교적 길지 만 논 리 는 매우 간단 합 니 다. 간단하게 정리 하면 다음 과 같 습 니 다. (여기 서/root/test 디 렉 터 리 가 이미 존재 한다 고 가정 합 니 다)
  • /root/test 디 렉 터 리 에 있 는 logical 라 는 이름 이 존재 하지 않 는 지 판단 하기 (1)    ==>touch 를 사용 하여 logical 파일 을 만 듭 니 다 (2) 존재 합 니 다.    파일    ==>logical 파일 을 삭제 하고 logical 디 렉 터 리 를 만 듭 니 다.    디렉토리    ==>논리 디 렉 터 리 삭제
  • 분명 한 것 은 '& &' 와 '| |' 으로 해결 할 수 있 지만 아래 는 표현 식 을 위해 그렇게 길 게 쓰 지 않 고 존재 여부 에 대한 판단 에 if 문 구 를 사 용 했 습 니 다.
    #!/bin/bash
    # Program:
    #       check the /root/test/logical
    # History:
    #       2015/07/26      XPleaf  First release
    PATH=$PATH:~/bin
    export PATH
    
    echo "check the /root/test/logical"
    
    test -e /root/test/logical
    i=$?
    if [ "$i" -eq "0" ];then
            test -f /root/test/logical && rm -rf /root/test/logical && mkdir /root/test/logical || rm -rf /root/test/logical
    else
            touch /root/test/logical
    fi

    실행 결과:
    상황 1:/root/test/logical 이 존재 하지 않 습 니 다.
    [root@moban test]# ls -l /root/test/logical
    ls:     /root/test/logical:          

    스 크 립 트 실행:
    [root@moban test]# sh sh04.sh 
    check the /root/test/logical
    [root@moban test]# ls -l /root/test/logical
    -rw-r--r-- 1 root root 0 7   26 11:05 /root/test/logical

    logical 파일 을 만 든 것 을 볼 수 있 습 니 다.
    상황 2:/root/test/logical 이 존재 하고 파일 (즉, 이전 실행 결과)
    [root@moban test]# sh sh04.sh              
    check the /root/test/logical
    [root@moban test]# ls -ld /root/test/logical
    drwxr-xr-x 2 root root 4096 7   26 11:06 /root/test/logical

    이 때 logic 는 디 렉 터 리 가 되 었 습 니 다. 즉, logic 파일 이 삭제 되 었 고 logic 디 렉 터 리 를 만 들 었 습 니 다.
    상황 3:/root/test/logical 이 존재 하고 디 렉 터 리 (즉, 이전 실행 결과)
    [root@moban test]# sh sh04.sh 
    check the /root/test/logical
    [root@moban test]# ls -l /root/test/logical
    ls:     /root/test/logical:          

    이 때/root/test/logical 이 존재 하지 않 습 니 다. 즉, 지난 단계 에 만 든 logical 디 렉 터 리 가 삭제 되 었 습 니 다.
    (4) 우 리 는/etc/passwd 에서 다음 과 같이 구분 하고 첫 번 째 열 은 계 정 이름 이라는 것 을 알 고 있 습 니 다.프로그램 을 쓰 십시오./etc/passwd 의 첫 번 째 열 을 꺼 낼 수 있 고, 열 마다 문자열 'The 1 account is' root' 로 표시 할 수 있 습 니 다. 그 1 은 줄 수 를 표시 합 니 다.
    강력 한 awk 로 바로 완성 가능:
    #!/bin/bash
    # Program:
    #       Remove the first list of the passwd and then output it
    #       like "The count line one is : the content of the passwd.
    # History:
    #       2015/07/26      XPleaf  First release
    PATH=$PATH:~/bain
    export PATH
    
    echo "$(awk -F ":" '{print "The " NR " account is " $1}' /etc/passwd)"

    실행 결과:
    [root@moban test]# sh sh05.sh 
    The 1 account is root
    The 2 account is bin
    The 3 account is daemon
    The 4 account is adm
    The 5 account is lp
    The 6 account is sync
    The 7 account is shutdown
    The 8 account is halt
    The 9 account is mail
    The 10 account is uucp
    The 11 account is operator
    The 12 account is games
    The 13 account is gopher
    The 14 account is ftp
    The 15 account is nobody
    The 16 account is dbus
    The 17 account is vcsa
    The 18 account is abrt
    The 19 account is haldaemon
    The 20 account is ntp
    The 21 account is saslauth
    The 22 account is postfix
    The 23 account is sshd
    The 24 account is tcpdump
    The 25 account is oldboy
    The 26 account is test
    The 27 account is apache
    The 28 account is www
    The 29 account is mysql

    이 문 제 는 좀 애매 합 니 다. 만약 에 이 문제 가 awk 를 보 는 문제 이거 나 그 자체 가 awk 에 대해 잘 알 고 있다 면 단번에 생각 할 수 있 습 니 다. 하지만 앞에서 말 한 두 가지 조건 이 없다 면 귀 찮 습 니 다. 처음에 awk 를 사용 할 줄 몰 랐 습 니 다. 아주 힘 든 방법 을 사 용 했 습 니 다. 줄 번 호 를 내 려 면 순환 을 사용 해 야 합 니 다. 1 부터 추가 해 야 합 니 다. 순환 을 사용 하려 면 순환 이 끝 난 것 을 알 아야 합 니 다.조건, 즉/etc/passwd 의 줄 수 를 알 아야 합 니 다. 줄 수 를 알 려 면 wc · · · · · 를 사용 한 다음 에 cut 로 첫 번 째 열 을 가 져 오고 sed 로 모든 줄 을 출력 해 야 합 니 다 (또한 순환).
    안 타 깝 게 도 마지막 에 소란 을 피 웠 습 니 다. 이론 적 으로 실현 할 수 있 습 니 다. 저 는 Linux 명령 행 에서 해 냈 습 니 다. 그러나 vim 으로 편집 할 때 아래 의 이 줄 에 문제 가 있 습 니 다. 즉, sed 의 문법 위 에 있 습 니 다.
    user=$(sed -n '$ip' /etc/passwd | cut -d':' -f 1)

    '$ip' 여기, 사실 저 는 출력 몇 번 째 줄 을 제어 하고 싶 습 니 다. i 는 순환 하 는 변수 입 니 다. 그런데 여 기 는 식별 할 수 없어 서 마지막 에 할 수 없습니다. 강력 한 awk 가 있어 서 다행 입 니 다. 그렇지 않 으 면 구덩이 에 빠 집 니 다! 두 가지 방법, 그 건 너무 멀 어 요!
    이 문법 위 에 있 는 것 에 대해 저도 왜 안 되 는 지 알 고 싶 습 니 다. 아 시 는 분 께 말씀 드 리 겠 습 니 다. 감사합니다.

    좋은 웹페이지 즐겨찾기