[shell]
"
) 와 single quote('
) 의 구분이 명확하다.echo "value is $foo"
⇒ "value is bar"
echo "value is $foo"
⇒ "value is $foo"
[함수]
bash shell에 함수를 쓸 수 있다.
$1
으로 쓰는 것 같다.mcd () {
mkdir -p "$1"
cd "$1"
}
source file
이라고 터미널에 치면 해당 file을 내가 쓰고 있는 셸에서 실행시키고 로드 시키겠다 라는 뜻이다. 즉 터미널에서 [mcd.sh](http://mcd.sh)
파일에서 만든 mcd
함수를 쓸 수 있는 것이다.mcd test
라고 입력하면 mcd 함수가 실행되는 것이고, test
는 argument로 들어간다. 그 argument는 $1
에서 인식해서 함수를 실행시키는 것이다.$는
0~9 까지 다양하고, $?
도 쓰는 것 같다.[기타1]
!!
(bangbang)이라는 명령어도 있다.||
은 OR, &&
은 AND 개ㅐ념이다.[기타2]
변수 안에 프로그램의 실행 결과를 담을 수도 있다. ex: foo=$(pwd)
pwd
는 현재 위치를 알려주는 프로그램인데 그 프로그램의 결과를 foo에 담는 의미이다.
[기타3]
$@
는 모든 argument를 담는다. 프로그램 입장에선 얼마나 많은 argument가 담겨올진 모르기 때문에, 받아온 argument들을 반복문으로 처리해줄 수 있다.
[예시 스크립트]
#!/bin/bash
echo "Starting program at $(date)"
echo "Running program $0 with $# arguments with pid $$"
for file in "$@"; do
grep foobar "$file" > /dev/null 2> /dev/null # 2>는 output stream을 하나 더 들어서 redirecting error를 함.
if [[ "$?" -ne 0 ]]; then
echo "File $file does not have any folder, adding one"
echo "# foobar" >> "$file"
fi
done
-ne
는 not equal의 줄임말이다.
참고 : &1
라는걸 쓸 수도 있네.
*.sh
라는 걸 통해 globbing이라는 개념을 배웠다.
[convert 프로그램 실습]
convert 프로그램을 사용하면 이미지 처리가 가능하다.
convert image.{png,jpg}
라는 식으로 curly bracket 안에 인자를 한꺼번에 받아서 처리할 수 있다.
sudo apt install imagemagick-6.q16
로 imagemagick 설치.sudo apt install imagemagick
[이미지 받아오기]
wget -qO test-image.jpg [https://c4.wallpaperflare.com/wallpaper/242/379/608/firecat-cat-fire-hd-wallpaper-preview.jpg](https://c4.wallpaperflare.com/wallpaper/242/379/608/firecat-cat-fire-hd-wallpaper-preview.jpg)
으로 아무 이미지 받아오기최종 명령어 : convert test-image.{jpg,png}
Convert, Resize and Alter Images Using the Linux Convert Command
[기타4]
touch ./project{1,2}/src/test/test/{1,2,3}.py
→ 한번에 여러개의 파일 만들 수 있음.
폴더 간 차이 알 수 있는 명령어
diff <(ls foo) <(ls bar)
[기타5]
문법체크해주는 shellcheck
라는 프로그램도 있음. 설치 필요.
man
보다 더 TMI 방출하는 tldr
을 쓰자. but 설치 필요.
현재 디렉토리 안에 있는 특정 파일을 재귀적으로 다 찾아주는 명령어 = find
예시 : find . -name src -type d
.
은 현재 디렉토리src
는 찾으려는 이름d
는 찾는 타입이 디렉토리. 파일은 f
예시 : find . -name "*.tmp" -exec rm {} \;
;
is encountered. The string {}
is replaced by the current file name being processed everywhere it occurs in the arguments to the command,.Linux shell, how to use the exec option in find with examples
[기타6]
locate missing
[기타7]
grep
에 대해 알아보자.
history
프로그램은 이때까지 쳤던 명령어 다 보여주는 프로그램
history substring search
: 이때까지 실행시켰던 특정 명령어 다시 돌아가서 다시 실행시키는 프로그램 같음. 검색 필요.[기타8]
cd 대신 쓸 수 있는 auto jump
라는 것도 있음.
[man ls
]를 읽고 다음과 같은 방식으로 파일을 나열하는ls
명령을 작성합니다.
출력 예시는 아래와 같습니다.
-rw-r--r-- 1 user group 1.1M Jan 14 09:53 baz
drwxr-xr-x 5 user group 160 Jan 14 09:53 .
-rw-r--r-- 1 user group 514 Jan 14 06:42 bar
-rw-r--r-- 1 user group 106M Jan 13 12:12 foo
drwx------+ 47 user group 1.5K Jan 12 18:08 ..
ls -alcht
으로 1차 달성
--color=auto
하면 컬러로 보여줌.다음을 수행하는 bash 함수marco
및polo
를 작성합니다. marco
를 실행할 때마다 현재 작업 디렉토리가 어떤 방식으로 저장되어야합니다. 그러면polo
를 실행할 때 어떤 디렉토리에 있든 상관없이 polo
가cd
를 수행해서 marco
를 실행 한 디렉토리로 돌아갑니다. 디버깅을 쉽게하기 위해marco.sh
파일에 코드를 작성하고source marco.sh
를 실행하여 쉘에 정의를 (재)로드 할 수 있습니다.
# 파일 명 : marco.sh
marco(){
cwd="$(pwd)"
echo $cwd
}
polo(){
cd $cwd
}
거의 실패하지 않는 명령이 있다고 가정 해보십시오. 그것을 디버그 하려고 출력을 캡처해야 하지만, 실패를 실행하는 데 시간이 오래 걸릴 수 있습니다. 실패 할 때까지 표준 출력 및 오류 스트림을 파일로 캡처하고 마지막에 앞의 모든 것을 출력하는 bash 스크립트를 작성하십시오. 스크립트가 실패하는 데 걸린 실행 횟수도 보고 할 수 있다면 보너스 포인트입니다.
#!/usr/bin/env bash
test(){
for num in "$@"; do
echo "$num" >> test.txt
n=$(($num % 100))
if [[ $n -eq 0 ]]; then
echo "fail result: $n" 2>> test.txt
break
fi
done
cat ./test.txt
}
[풀이]
거의 실패하지 않는 명령을 만들기 어려워서, 비정상적인 명령어 argument가 들어오면(숫자를 받아야하는데, 문자를 받는다거나) 실패한다고 간주해서 처리하는 코드를 짰다.
표준 출력 및 오류 스트림을 capture to file로 하기 위해 1>
과 2>
를 test.txt로 보낸다.
마지막에 앞의 모든 것을 출력 : cat으로 출력하기
강의에서 다루었듯이find
의 -exec
는 검색하는 파일에 대한 작업을 수행하는데 매우 강력합니다. 그러나 zip 파일을 만드는 것과 같이 모든 파일로 작업을 수행하려면 어떻게해야합니까? 지금까지 본 것처럼 명령은 인수와 STDIN 모두에서 입력을받습니다. 명령을 파이핑 할 때 STDOUT을 STDIN에 연결하지만 ‘tar’와 같은 일부 명령은 인수에서 입력을받습니다.
이러한 문제를 해결하기 위해 STDIN을 인수로 사용하여 명령을 실행하는 [xargs
] 명령이 있습니다. 예를 들어ls | xargs rm
은 현재 디렉토리의 파일을 삭제합니다.
당신의 임무는 폴더에서 모든 HTML 파일을 재귀적으로 찾아서 zip 파일을 만드는 명령을 작성하는 것입니다. 파일에 공백이 있어도 명령은 작동되어야 합니다. (hint: check -d
flag for xargs
)
If you’re on macOS, note that the default BSD find is different from the one included in GNU coreutils. You can use -print0 on find and the -0 flag on xargs. As a macOS user, you should be aware that command-line utilities shipped with macOS may differ from the GNU counterparts; you can install the GNU versions if you like by using brew.
문제 쪼개기
find /folder -name "*.html" -type f | xargs -0
find /folder -name "*.html" -type f | xargs -0 zip myzip.zip
value1 value2 value3
gzip -9 {{file.ext}}
xargs -d '\n'
를 써보자.최종 명령어 : find . -name "*.html" -type f | xargs -d '\n' gzip -9
(고급) 명령 또는 스크립트를 작성하여 디렉토리에서 가장 최근에 수정 된 파일을 재귀적으로 찾으시오. 그리고 모든 파일을 최신순으로 나열 할 수 있습니까?
find와 ls를 같이 쓰면 될 것 같다.
최종 명령어 : find $1 -type f -print0 | xargs -0 stat --format '%Y :%y %n' | sort -nr | cut -d: -f2- | head
명령어 구문 해석해보기
find $1 : find에서 받는 기준($1)을, 뒤에 나오는 xargs ~~
로 받겠다.
stat : 파일 정보를 보여주기
-c --format=FORMAT
%Y
: time of last data modification, seconds since Epoch(타임스탬프인듯)%y
: time of last data modification, human-readable%n
: file namesort
: 파일 정렬하기
- n
: 숫자로 정렬하기
- r
: 정렬 반대로하기(기본이 오름차순인듯)
cut
: 파일에서 필드(데이터)를 뽑아내기
- -d
구분자 : 필드를 구분하는 문자를 지정한다. 디폴트는 탭 문자다.
-f
구분자 : 잘라낼 필드(데이터) 정하기 -f2-
라는건, delimiter로 구분 이후 범위를 "2번째 필드부터 끝까지"로 하겠다.'%Y :%y %n'
으로 데이터가 나오니까 -d:
로 나누면 %Y | %y %n
으로 나눠질거고 f2
가 적용되었으니 %y
부터 까지 데이터를 뽑아내겠다. 라는 의미이다.head
: 파일의 첫번째라인을 뽑아내겠다.