-
셸 스크립트 작성하기Linux 2024. 11. 19. 00:37반응형
Shebang 지정
상단에 shebang(#!, 스크립트를 실행할 셸/인터프리터)을 지정해줘야 한다.
지정하지 않았을 경우 기본 셸로 실행된다.
기본 셸은 다음 명령어로 확인할 수 있다.
echo $SHELL
bash일 경우
#!/bin/bash
zsh일 경우
#!/bin/zsh
zsh에서만 지원되는 문법을 사용할 경우 상단에 zsh 명시를 해줘야 제대로 실행된다.
주석 처리
#을 붙여 나타낸다.
e.g.
# Installation script for ros2
변수
변수 선언
일반적으로 일반 변수는 snake_case로, 환경 변수는 SCREAMING_SNAKE_CASE로 쓰는 것 같다.
= 전후로 공백이 없어야 한다.
e.g.
workspace_path="/home/user/catkin_ws"
변수 사용
$를 붙여 나타낼 수 있다.
중괄호를 사용하여 가독성을 높일 수도 있다.
workspace_path="/home/user/catkin_ws" echo "Path is set: $workspace_path" echo "Path is set: ${workspace_path}"
Path is set: /home/user/catkin_ws Path is set: /home/user/catkin_ws
출력(echo)
e.g.
echo "Installing ROS2 Humble..."
Installing ROS2 Humble...
입력(read)
e.g.
read workspace_path echo "Path is set: $workspace_path"
/home/user/catkin_ws Path is set: /home/user/catkin_ws
조건문
다음과 같은 형태로 사용 가능하다.
if [ condition1 ]; then command1 elif [ condition2 ]; then command2 else command3 fi
조건 뒤에 세미콜론을 빼려면 then을 다음 줄로 내려야 한다.
if [ condition1 ] then command1 elif [ condition2 ] then command2 else command3 fi
조건이 여러 개일 경우 &&, ||를 사용하여 나타낼 수 있다.
if [ condition1 ] && [ condition2 ]; then command1 else command2 fi if [ condition1 ] || [ condition2 ]; then command1 else command2 fi
조건 옵션
-f 파일이 존재하는지 확인 -d 디렉토리가 존재하는지 확인 -e 파일이 존재하는지 확인 (파일, 디렉토리 포함 모든 유형 체크) -r 읽기 가능한 파일인지 확인 -w 쓰기 가능한 파일인지 확인 -x 실행 가능한 파일인지 확인 -s 파일 크기가 0보다 큰지 확인 (empty check) e.g.
if [ -f "test.txt" ]; then echo "Test file exists." else echo "No test file exists." fi
파일이 존재할 경우
Test file exists.
파일이 존재하지 않을 경우
No test file exists.
숫자 비교 연산자
-eq 같음(equal) -ne 같지 않음(not equal) -lt 작음(less than) -le 작거나 같음(less or equal) -gt 큼(greater than) -ge 크거나 같음(greater or equal) e.g.
num1=7 num2=28 if [ $num1 -lt $num2 ]; then echo "$num1 is less than $num2." else echo "$num1 is not less than $num2." fi
7 is less than 28.
문자열 비교 연산자
= 같음 != 같지 않음 -z 비어 있음(zero length, empty()) -n 비어 있지 않음(non-zero length, !empty()) e.g.
test_file_path="/home/user/test.txt" if [ -z "$test_file_path" ]; then echo "File path is not set." else echo "File path is set." fi
File path is set.
빈 문자열일 경우
test_file_path="" if [ -z "$test_file_path" ]; then echo "File path is not set." else echo "File path is set." fi
File path is not set.
$test_file_path가 아닌 "$test_file_path"로 쓰는 것이 좋다.
전자로 써도 되지만 test_file_path 변수가 비어 있거나 공백이 들어있을 경우에는 에러가 발생한다.
따라서 문자열 비교 시 변수를 큰 따옴표로 감싸주는 것이 좋다.
그리고 bash와 zsh로 실행할 거라면 조건에 [] 대신 [[]]를 사용하는 것이 좋다.
안전성과 유연성이 강화된 버전으로 공백으로 인한 에러를 방지해주고, 안에 정규식도 사용할 수 있다고 한다.
단, POSIX 표준이 아니라 모든 셸에서 사용할 수는 없는 듯.
정상 실행
test_file_path="" if [[ "$test_file_path" = "/home/user/test.txt" ]]; then echo "Same string." else echo "Different string." fi
Different string.
에러 발생
test_file_path="" if [ $test_file_path = "/home/user/test.txt" ]; then echo "Same string." else echo "Different string." fi
./test-script.sh:6: parse error: condition expected: = Different string.
반복문
while문
다음과 같은 형태로 사용한다.
while [ condition ]; do command done
e.g.
i=0 while [ $i -lt 5 ]; do echo "num: $i" ((i++)) done
num: 0 num: 1 num: 2 num: 3 num: 4
(()) 안에 C스타일 구문을 넣어 작성할 수 있다.
for문
다음과 같은 형태로 사용한다.
for var in list; do command done
e.g.
for i in {0..4}; do echo "num: $i" done
num: 0 num: 1 num: 2 num: 3 num: 4
함수
함수 선언
다음과 같은 형태로 사용한다.
function_name() { command }
e.g.
rosv2() { echo "Activate ros2" }
함수 호출
함수 이름을 그냥 쓰면 된다.
e.g.
rosv2
Activate ros2
function 키워드를 명시적으로 써서 가독성을 높일 수도 있는데, 이때는 괄호를 떼고 써도 된다.
근데 그냥 위처럼 쓰는 게 편한 듯.
function rosv2 { echo "Activate ros2" }
인자가 있을 경우
$1, $2, …와 같은 형태로 여러 개의 인자를 넘겨줄 수 있다.
e.g.
package_install() { ans=$1 if [ "$ans" = "yes" ]; then echo "do installation." else echo "do not installation." fi } package_install "yes"
do installation.
에러 처리/디버깅
set 명령어에 여러 옵션을 줘서 에러 처리나 디버깅에 사용할 수 있다.
사용 가능한 옵션
엄청 많지만 일부만 정리한다.
-n 스크립트를 실행하지 않고 문법 오류만 체크한다. (noexec) -e 에러 발생 시 스크립트 실행을 즉각 중단한다. (errexit) -u 선언되지 않은 변수 사용 시 에러를 출력한다. (nounset) -x 실행되는 명령어와 각 명령어에 전달되는 인수를 터미널에 출력한다. (xtrace) -x 추적 시작, +x 추적 종료임을 이용해서 다음과 같이 일부 구간에서만 사용할 수도 있다.
set -x echo "Trace on." set +x echo "Trace off." set -x echo "Trace on again."
+./test-script.sh:5> echo 'Trace on.' Trace on. +./test-script.sh:7> set +x Trace off. +./test-script.sh:11> echo 'Trace on again.' Trace on again.
스크립트 실행
실행 권한 부여
작성한 스크립트에 실행 권한을 부여해줘야 실행할 수 있다.
chmod +x test-script.sh
실행 방법
방법 1) 현재 로그인 된 셸에서 스크립트를 실행할 수 있다.
./test-script.sh
방법 2) 셸을 직접 지정해준 후 실행할 수도 있다.
shebang으로 실행할 셸을 지정하지 않았을 경우 지정해준 후 실행하는 것이 좋다.
bash일 경우
bash test-script.sh
zsh일 경우
zsh test-script.sh
스크립트 예시
공식 문서에 나와 있는 설치 가이드대로 우분투 22.04에 ROS2 Humble Hawksbill desktop를 설치하고, 워크 스페이스를 생성한 뒤 빌드까지 해주는 스크립트를 작성해보자. (Bash 기준)
#!/bin/bash # Set locale current_lang=$(locale | grep LANG= | cut -d= -f2) if [[ "$current_lang" != "en_US.UTF-8" ]]; then echo "Set UTF-8 locale." sudo apt update && sudo apt install -y locales sudo locale-gen en_US.UTF-8 sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 export LANG=en_US.UTF-8 else echo "Locale is already set." fi # Set ubuntu universe repository sudo apt install -y software-properties-common sudo add-apt-repository -y universe # Add ROS2 GPG key sudo apt update && sudo apt install curl -y sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg # Add the repository in sources list echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null # Update the packages to the latest version sudo apt update -y sudo apt upgrade -y echo "Repository setup complete." # Install desktop version sudo apt install -y ros-humble-desktop # Install development tools sudo apt install -y ros-dev-tools # Create workspace install_path="$HOME/ros2_ws" mkdir -p "${install_path}/src" cd $install_path # Source bash file source /opt/ros/humble/setup.bash echo "Desktop installation complete." # Install colcon sudo apt install -y python3-colcon-common-extensions echo "Colcon installation complete." # Build colcon build echo "All installations are complete."
설치가 끝나면 source 해준 후, 데모 노드를 실행해보고 잘 되는지 확인한다.
source /opt/ros/humble/setup.bash ros2 run demo_nodes_cpp talker
[INFO] [1732033177.977694275] [talker]: Publishing: 'Hello World: 1' [INFO] [1732033178.977679343] [talker]: Publishing: 'Hello World: 2' [INFO] [1732033179.977680602] [talker]: Publishing: 'Hello World: 3' [INFO] [1732033180.977688773] [talker]: Publishing: 'Hello World: 4' [INFO] [1732033181.977681876] [talker]: Publishing: 'Hello World: 5' [INFO] [1732033182.977708902] [talker]: Publishing: 'Hello World: 6' [INFO] [1732033183.977707750] [talker]: Publishing: 'Hello World: 7' [INFO] [1732033184.977713308] [talker]: Publishing: 'Hello World: 8' [INFO] [1732033185.977717267] [talker]: Publishing: 'Hello World: 9' [INFO] [1732033186.977715467] [talker]: Publishing: 'Hello World: 10' [INFO] [1732033187.977729032] [talker]: Publishing: 'Hello World: 11'
잘 된다.
반응형'Linux' 카테고리의 다른 글
udev rules 심볼릭링크 설정 - USB 장치 포트 이름 고정하기 (0) 2023.03.01 cat 명령어 - 파일 내용 출력, 연결 (0) 2023.03.01 리눅스 자주 사용하는 명령어 모음 (0) 2023.02.27