많은 파일 이름에서 특정 패턴을 찾아서 일괄 변경하기 위한 시도는 오래전부터 있었습니다.아마도 가장 흔한 방법이 rename 일텐데, rename의 설치 방법에 따라 동작 여부가 약간 달라 문제가 있죠. 일반 pkg에 built-in되어 있는 rename은 파일 명에서 패턴을 찾아 변경하는 옵션이 제공되지 않습니다.그래서 shell로 도전하게 되었습니다. 일단 결과부터 놓고 풀어나갑니다.아래는 파일 이름에서 A_A를 찾아 B_B로 변경하는 명령어 입니다. $ find . -type f | xargs -I{} sh -c 'mv -v $0 ${0/A_A/B_B}' {} ; 하나하나 풀어가며 의미를 알아봅니다. $ find . -type f현재 폴더에서 파일 리스트를 가져옵니다. $ find . -type f..
리눅스에서 디렉토리의 사이즈를 검사할 때 주로 사용되는 명령어는 du 입니다. 명령어를 활용하면 되지만 어느 디렉토리가 용량을 많이 차지하는지 찾기 위해서는 각 폴더 별로 아래와 같은 형태의 명령어를 실행해봐야 합니다. $ du -sh /bin 디렉토리가 많은 경우 이것 또한 노가다(?)가 될 수 있기 때문에 간단하지만 유용한 스크립트를 작성했네요. 현재 디렉토리 하위에 있는 디렉토리를 기본 depth 1부터 인자로 입력 받는 maxdepth까지 du -sh 를 자동으로 해줍니다. #!/bin/sh DEPTH=1 if [ "$1" = "-h" ] || [ "$1" = "--help" ] || [ "$1" = "help" ] || [ "$1" = "h" ] ;then cat
ls나 cat 등 터미널 명령어의 결과를 배열에 저장하고 사용해야 하는 경우가 종종 있습니다. shell script에서 일반적인 배열은 아래와 같이 사용합니다. AAA=("aa" "bb" "cc") 그리고 읽을 때는 아래처럼 읽겠죠? echo ${AAA[0]}, ${AAA[1]} 그럼 이제 터미널 명령어의 경우를 살펴봅시다. 터미널 명령어의 결과를 변수로 받는 일반적인 방법인 BBB=$(echo "aa bb cc") 처럼 사용할 경우 결과는 엉뚱합니다. echo ${BBB[0]}로 출력해 봤을때 결과로 aa를 기대하지만, 실제로는 aa bb cc가 출력 됩니다. 결과를 일반적인 배열로 받기 위해서는 아래처럼 한번 더 괄호로 감싸줘야 합니다. BBB=($(echo "aa bb cc")) 앞으로는 여기에 ..
shell script 에서 때로는 문자열 패턴의 일치 여부를 확인하는 것이 아니라 포함되는지 확인해야 하는 경우가 있습니다. 아래 예시를 살펴보겠습니다. AA="My name is oops" BB="oops" 변수 $BB가 $AA에 포함되는지 확인하는 방법에는 여러가지가 있겠지만 아래 두 가지 방법을 소개합니다. ( Node.js 로 비유하자면 str.includes(word) 같은 역할이겠죠 ) #!/bin/sh AA="My name is oops" BB="name" if [[ "$AA" == *"name"* ]];then echo "1st find it" fi if [[ "$AA" =~ "name" ]];then echo "2nd find it" fi 문자열 패턴을 이용한 * 방법이 있고, =~ 를..
흔히 $*와 $@를 구분 없이 많이 사용하고 있는데, 사실 약간은 다르다. 레퍼런스에 보면 아래와 같이 정의되어 있다. "$*"All the positional parameters (as a single word) * "$@"All the positional parameters (as separate strings) 무슨 뜻이냐면, $*는 모든 parameter를 하나의 단어로 취급한다는 의미고, $@는 별도의 문자로 취급한다는 의미다. (응?) 다시말해, $*는 입력되는 모든 parameter를 한개의 단어로 취급한다는 뜻. $@는 공백으로 구분된 별도의 문자열로 취급한다는 의미다. 아래와 같은 스크립트 코드가 있다. #!/bin/sh echo "=================" echo "\$@ se..
간혹 shell에서 어떠한 값을 변수로 사용해야 하는 경우가 생깁니다.이를테면 특정 프로세스에서 사용중인 file descriptor를 확인하기 위해서는 아래와 같겠습니다. 우선 cron으로 테스트 해보면 아래와 같이 cron의 pid(644)를 구할 수 있습니다. 얻은 pid(644)를 이용해서 사용중인 file descriptor를 아래와 같이 확인 할 수 있습니다. 하지만 두번에 걸쳐 실행되어야 하는 명령어는 불편할때가 있습니다. 위 내용은 아래와 같이 한번에 수행할 수 있습니다. 이 예제는 $()의 활용에 대한 부분입니다.$()가 아니더라도 |(pipe)나 환경변수 등을 이용해서 한번에 수행할 수 있는 방법은 많이 존재합니다.
shell script에서 함수 구현은 아래와 같습니다.#!/bin/sh add() { echo "test" } add 결과 : test 네. 무척 간단하죠? 그럼 이번에는 위 함수에 인자를 전달해보겠습니다. #!/bin/sh add() { echo $@ } add 1 3 결과 : 1 3$@는 배열 전부를 출력하는 문장입니다. 이번에는 결과를 return 받아보도록 합니다.add() { return $(($1+$2)) } add 1 3 echo $? 결과 : 4 ( "$((" 와 "))" 는 수학 계산으로 인식 됩니다 ) 굉장히 간한한 코드겠지만, shell script에서 함수 사용법을 엿볼수 있는 예제입니다.함수의 return과 인자 전달도 말입니다.
쉘스크립트의 종류는 다양한데 그중 bash와 ash를 뽑아봅니다. 이야기 하고자하는 내용은 두 스크립트의 차이입니다. 보통 ash는 busybox를 통해 사용가능한데요, 지금 본인이 개발하고 있는 스크립트가 어떤 쉘로 실행되는지 (필히)확인이 필요합니다. 이유는 동일해보이는 스크립트지만 지원가능한 문법이 다르기 때문입니다. 예를들면 아래와 같은 배열 (우리에게 친숙한) 을 bash에서 사용합니다. daemon_list=("oops" "test") 참조는 아래처럼 하겠지요. echo ${daemon_list[@]} 하지만 이 내용이 ash로 실행되면 바로 아래와 같은 syntax error를 출력하고 실행되지 않습니다. (ash는 bash스타일의 배열을 지원하지 않습니다.) ./oops: line 3: s..
프로그램 개발만큼 중요한것이 사용자에게 프로그램의 정보(사용법)를 알리는 help입니다. 그런 면에서.. help함수를 구현하고 echo로 도움말을 출력하는 기법 자주 애용했었는데요,예를 들면 아래와 같습니다. #!/bin/sh help() { echo "This is a test message." echo "Maybe help()." } [ -z "$1" ] && help 하지만 라인수가 많아졌을때 관리적인 측면에서 좋지 않습니다.또한 결과 출력 시에 줄 맞춤에도 다소 문제가 있지요, 해서 사용하는 방법이 아래와 같이 존재합니다. #!/bin/sh help() { cat
분산버전관리시스템을 사용하면서 git clone시에 매번 password를 입력하는 것이 불편했습니다. 그 불편함은 인터넷에 널린.. ssh-keygen을 사용해서 개인키를 서버의 .ssh/authorized_keys 에 등록해서패스워드를 생략하는 방법으로 해소했는데요. 이 방법을 스크립트화 시켜보았습니다.(여러분의 시간은 소중하니까요) #!/bin/sh ID_RSA=~/.ssh/id_rsa.pub # id_rsa.pub 파일이 없을때만 ssh-keygen을 수행합니다. if [ ! -f $ID_RSA ]; then expect -c "spawn ssh-keygen" \ -c "expect -re \":\"" \ -c "send \"\r\"" \ -c "expect -re \":\"" \ -c "send..
shell에서 awk의 내장함수인 substr은 문자열 전체가 아닌 일부를 비교할때 사용합니다.아래 예제를 살펴봅니다. #!/bin/sh echo | awk '{ print substr("my name is oops",12,4)}' 입력 받은 "my name is oops"에서 12번째 자리인 o 부터 4개를 출력합니다.응용하면 아래와 같은 코드도 구현할 수 있습니다. #!/bin/sh NAME=`echo | awk '{name=substr("my name is oops",12,4);print name}'` echo -n "name?" echo $NAME 실행 결과는 다음과 같습니다. $ ./oops name?oops 이렇게 되면 NAME 변수를 코드 내에서 활용할 수 있게 되겠지요? 이외에도 내장함수는..
특정 폴더에 있는 script를 실행하는 shell을 작성해야 할 일이 생겼습니다. 해당 경로에 있는 script를 하드코딩으로 실행해도 되겠지만, 나중에 리스트가 많아지는 경우를 생각해서 확장성에 초점을 맞춘 코드 입니다.#!/bin/sh APPS_SCRIPT=/test/apps/ if [ -e "$APPS_SCRIPT" ]; then SCRIPT_LIST=`ls $APPS_SCRIPT` for SCRIPT in $SCRIPT_LIST; do $APPS_SCRIPT/$SCRIPT done fi shell의 if 문법과 for, 말고는 특별한 내용은 없습니다.
- Total
- Today
- Yesterday