Shell 스 크 립 트 빠 른 입문
글 목록
shell
스 크 립 트 는 모든 Liux 개발 자 에 게 필요 한 기능 으로 다른 스 크 립 트 언어 에 비해shell
은 Liux 자체 에 더욱 가 깝 고 bash 와 고도 로 통합 되 며 많은 응용 에서 (특히 텍스트 처리 와 IO 와 관련 된) 더욱 높 은 용이 성과 간결 성 을 가진다.본 고 를 읽 는 데 일정한 기초 가 필요 하 다. 필 자 는 글 을 쓸 때 독 자 를 기대한다.
변수 와 함수
변량
변수 정의 와 할당 의 표준 형식 은
=
이 고 단독 성명 이 필요 하지 않 습 니 다. 등호 근처에 빈 칸 이 있 으 면 안 됩 니 다. 예 를 들 어 다음 과 같 습 니 다.#!/bin/bash
a=35
name="williams"
_o="o"
_ld='ld'
_old="$_o$_ld" # `$` ( )
echo $name is $a years $_old #
unset _o # ( )
sh
명령 으로 스 크 립 트 를 실행 하여 출력 을 얻 습 니 다.williams is 35 years old
함수 정의
함수 의 정의 방식 은 다음 과 같다.
func1() {
echo $1 # $1
echo $# # $#
}
func2() {
return $(($1+$2)) # ( )
}
a=3
func1 "oops" 233 #
func2 $a 2
echo $? # /
스 크 립 트 실행, 출력 획득
oops
2
6
명령 과 IO
명령 과 IO 는
shell
스 크 립 트 에서 가장 중요 한 부분 으로 파이프 시스템 의 도움 을 받 아 스 크 립 트 는 시스템 명령 과 프로그램 과 쉽게 상호작용 할 수 있 습 니 다.다음은 간단 한 예 이다.
txts=`ls | egrep *.\.txt` # ls , egrep .txt
# txts=$(ls | egrep *.\.txt)
echo $txts # txt
이 곳 의 '기 호 는
Ruby
과 비슷 하여 명령 을 실행 하고
의 내용 을 문자열 값 으로 되 돌려 줍 니 다.따라서 우리 가 얻 은 변 수 는
txts
이 bash 에서 명령 을 수행 할 때 콘 솔 에서 출력 하 는 내용 입 니 다.예 를 들 어 파일 내용 을 읽 거나 현재 사용 자 를 가 져 오 면 상기 방법 을 이용 하여 쉽게 실현 할 수 있다.
text=`cat hello.txt` # => text hello.txt
username=`whoami` # => username
echo $username # => , root
파일 에 출력 하 는 것 도 간단 하 다.
text1="hello,"
text2="world!"
echo -n $text1 > hello.txt # (n )
echo $text2 >> hello.txt # hello.txt
위 스 크 립 트 를 실행 하면 디 렉 터 리 에
hello.txt
이 나타 납 니 다. 그 안에 한 줄 의 텍스트 가 있 습 니 다: hello,world!
read
명령 을 사용 하면 콘 솔 에서 변 수 를 읽 을 수 있 습 니 다 (Haskell
과 유사 한 read)#!/bin/bash
# A + B Problem ~
read a
read b
c=$(($a+$b))
echo $a + $b = $c # => e.g. 1 + 3 = 4
주의해 야 할 것 은 변수 도 ` 기호 에 포 함 된 명령 에 참여 할 수 있다 는 것 이다. 예 를 들 어:
text="eureka!"
text=`echo $text | tr 'a-z' 'A-Z'` # tr
echo $text
상기 스 크 립 트 출력 은
EUREKA!
입 니 다.연산 및 프로 세 스 제어
연산 과 괄호
shell
스 크 립 트 의 연산 을 언급 하면 가장 자주 사용 하 는 괄호 몇 가 지 를 소개 해 야 한다.쌍 소괄호
(( ))
은 산술 (정형) 연산 에 사용 되 는 동시에 일부 특수 기능 에 도 사용 할 수 있다.a=2
b=$(( ($a + 1) / 2 )) # => b = (2 + 1) / 2 = 1
rd=$((RANDOM % 100)) # => rd 0~99
c=$(( $a > 1 )) # => a > 1 , 1 (true)
d=$(expr $a + $b) # => $(($a + $b))
중 괄호
[ ]
과 이중 괄호 [[ ]]
은 비교 연산 에 사용 되 는데 그 중에서 [ ]
은 실제 적 으로 Liux 에서 test
명령 에 대한 암시 적 호출 이다 (반드시 주의해 야 한다: 셸 의 정의 에서 true
은 0 이 고 false
은 1 이다).a=2; b=1; c=3; #
str='ray-tracing'
[ $a -gt $b ] # , [$a -gt $b]
echo $? # $? => 0 (true)
[ $c -eq $c ] # test $c -eq $c
echo $? # 0 (true)
[ $a -ne 1 -a $c -eq 3 ] # a != 1 && c == 3
[ $a -ne 1 -o $c -ne 3 ] # a != 1 || c != 3
[ $str != 'ray-tracing' ] # 1 (false)
[ $str = 'ray' ] # 1 (false)
[[ a + b = 3 && a != b ]] # 0 (true)
# bash
test
명령 의 사용 을 익히 는 것 은 정확 한 논리 연산 표현 식 을 쓰 는 데 도움 이 되 므 로 독자 들 은 위 키 피 디 아 를 참고 하여 더 많은 것 을 알 수 있다.이중 괄호
[[ ]]
은 중 괄호 보다 인성 화 되 어 C
과 비슷 한 표현 식 을 쉽게 감당 할 수 있 음 을 알 수 있다.대괄호
{}
은 범위 와 배 치 를 정의 하 는 데 사용 되 는데 여기 서 상세 하 게 논술 하지 않 고 관심 이 있 는 독 자 는 이 블 로 그 를 참고 할 수 있다.분기 문
Python
과 달리 셸 스 크 립 트 는 어떠한 형식의 들 여 쓰기 도 강요 하지 않 기 때문에 프로 세 스 문 구 는 끝 기호 가 있어 야 합 니 다.전형 적 인 if 문 구 는 다음 과 같다.
read a
echo -n $a is
b=$(( $a % 2 ))
if [ $b -eq 0 ]; then # a
echo " even"
else
echo " odd"
fi
if [ `whoami` = 'root' ]; then
echo "and you are root ?"
elif [ `whoami` = 'phosphorus15' ]; then # C else if
echo "seriously ?"
else
echo "alright ~"
fi
메모: 순환 이 든 분기 제어 든 빈 블록 이 있 으 면 안 됩 니 다. 즉, 나타 나 면 안 됩 니 다.
if [ `whoami` = 'root' ]; then # !
else
echo "oops !"
fi
순환 문
많은 고급 언어 와 마찬가지 로 셸 은 몇 가지 사용 가능 한 순환 제어 구 조 를 가지 고 필 자 는 여기 서 자신 이 자주 사용 하 는 몇 가 지 를 소개 할 것 이다.
a=1; b=0;
while [ $a -le 100 ]; do # while (( $a <= 100 )); do
b=$(($a+$b))
a=$(($a+1)) # bash ((a++))
done
echo $b # 5050
a=1; b=0;
until [ $a -gt 100 ]; do
b=$(($a+$b))
a=$(($a+1))
done
echo $b # 5050
은 사실 while 를 거꾸로 쓰 는 거 예요. 너무 힘 들 지 않 아 요?괜찮아 ~ 산술 연산 은 원래 셸 스 크 립 트 의 특기 가 아니 야. 다음은 네가 볼 것 이 야 말로 셸 의 진정한 정수 야.for i in Apple Juice Cake; do
echo do you like $i ?
done
for j in `seq 0 3`; do
echo $j
done
for k in `seq 65 70`; do
echo $k | awk '{printf("%c", $1)}' # ascii
# bash printf, printf \\x$(printf %x $k)
done
for c in {0..8..2}; do # 0~8
echo $c
done
# , bash
출력 내용: do you like Apple ?
do you like Juice ?
do you like Cake ?
0
1
2
3
ABCDEF
예상 하기 어렵 지 않 습 니 다. 우리 의 이전 while
순환 은 s=0
for i in `seq 1 100`; do # 1 100
s=$(($s+$i))
done
echo $s
을 쓸 수 있 습 니 다. 만약 에 우리 가 디 렉 터 리 에 있 는 모든 파일 에 백업 을 만 들 려 면 이렇게 쓸 수 있 습 니 다. for file in $(ls); do #
# file ,
if [ "$(file $file | grep -o directory)" != 'directory' ]
then
cp $file "$file.bak" # cp
echo backup $file
fi
done
bash
의 지 지 를 받 을 수 있 을 뿐 sh
의 지 지 를 받 을 수 없다.스 크 립 트 를 sh
으로 실행 하 는 습관 이 많은 것 을 감안 하여 스 크 립 트 를 작성 할 때 이러한 문 구 를 사용 하 는 것 을 피해 야 합 니 다.표준 for
문 구 는 bash
만 지원 할 수 있 습 니 다. 쓰 는 방법 은 다음 과 같 습 니 다. for((i=0;i<10;i++));
do
echo $(expr 10 - $i) # $((10 - $i))
done
~ 아 ~ Old good days, ~ 짙 은 C
의 맛 이 물씬 풍 깁 니 다.그래도 상술 한 바 와 같이 사용 을 추천 하지 않 습 니 다.부가 내용
배열
배열 은
bash
에서 만 사용 할 수 있 는 기능 으로 많은 언어 에서 배열 과 매우 비슷 하 다.정의 방식 은 다음 과 같 습 니 다.a=(2 7 5 6 8 1 3 0 4 9)
b=({0..9}) # 0 1 2 3 4 5 6 7 8 9
c=({0..9..2} {1..9..2}) # 0 2 4 6 8 1 3 5 7 9
strs=("tomato" "potato" "onion" "lettuce" "okra")
misc=("str1" 1 "str2" 5 1)
배열 은 아래 표 시 를 통 해 직접 접근 하거나 펼 칠 수 있 습 니 다.
echo ${a[0]} ${a[3]} # => 2 6
echo ${b[@]} # => b , : 0 1 2 3 4 5 6 7 8 9
b[0]=10 # 10
echo ${b[@]} # => b , : 10 1 2 3 4 5 6 7 8 9
echo ${#misc[@]} # => misc , 5
echo ${strs[@]:1:3} # => 1~3 , : potato onion lettuce
unset c[3] # => 3
이에 따라
for each
순환 으로 배열 을 빠르게 옮 겨 다 닐 수 있 습 니 다.for e in ${c[@]}; do
echo -n "$e "
done
# , 0 2 4 8 1 3 5 7 9
작은 매듭
이로써 독 자 는 기본 셸 스 크 립 트 작성 의 기본 기 교 를 익 혔 을 것 이다. 만약 에 더욱 숙련 되 려 면 독자 스스로 간단 한 스 크 립 트 를 써 서 이 해 를 깊이 있 게 하 는 것 을 추천한다.또한 Liux 시스템 의 관련 명령 도 더 잘 알 아야 한다.
마지막 으로 필 자 는 상술 한 내용 을 복습 하 는 작은 발 을 내 놓 았 다.
#!/bin/sh
factorial() {
if [ $1 -eq 0 ]; then return 1; fi
s=1
for i in `seq 1 $1`; do
s=$(($s*$i)) #
trace[$(expr $i - 1)]=$s #
done
echo calculation trace [${trace[@]}] #
return $s
}
if [ `whoami` = 'root' ]; then
echo root is not allow to execute this script!
exit
fi
if [ $# -lt 2 ]; then
echo usage : sh fac.sh [n] [output] > /dev/stderr #
elif [ $1 -lt 0 ]; then
echo n cannot be less than zero ! > /dev/stderr
elif [ -z "$2" ]; then #
echo output file cannot be null ! > /dev/stderr
else
factorial $1
echo $1!=$? > "$2"
fi
스 크 립 트 실행 결과:
phosphorus15@ubuntu:~/Documents$ sh fac.sh
usage : sh fac.sh [n] [output]
phosphorus15@ubuntu:~/Documents$ sh fac.sh 1
usage : sh fac.sh [n] [output]
phosphorus15@ubuntu:~/Documents$ sh fac.sh 1 fac.txt
calculation trace [1]
phosphorus15@ubuntu:~/Documents$ file fac.txt
fac.txt: ASCII text
phosphorus15@ubuntu:~/Documents$ cat fac.txt
1!=1
phosphorus15@ubuntu:~/Documents$ sh fac.sh 5 fac.txt
calculation trace [1 2 6 24 120]
phosphorus15@ubuntu:~/Documents$ cat fac.txt
5!=120
phosphorus15@ubuntu:~/Documents$ sudo sh fac.sh 5 fac.txt
[sudo] password for phosphorus15:
root is not allow to execute this script!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.