alias 에 따옴표(홑/겹) 넣기.

다소 복잡한 alias 를 만들었는데, 따옴표를 넣어야 하는 상황이라 오류가 발생했다.

넣으려는 명령은 이랬다.

updl=$(sudo opkg list-upgradable | cut -f 1 -d ' ') ; if [[ $(wc -l <<< $updl) > 1 ]] ; then xargs sudo opkg upgrade <<< "$updl" ; else echo '지금은 없네요' ; fi"

Openwrt opkg 에서 판올림을 하는 명령을 살짝 변형해봤다.
판올림이 가능한 지 먼저 확인하고, 가능한 꾸러미가 있으면( wc -l 로 확인) 판올림을 수행하고, 없다면 “없네요”를 출력하고 끝낸다. 명령어로 넣으면 그냥 간단한데..

이걸 Alias 에 넣으려니 오작동이 생겨나버렸다.

alias="updl=$(sudo opkg list-upgradable | cut -f 1 -d ' ') ; if [[ $(wc -l <<< $updl) > 1 ]] ; then xargs sudo opkg upgrade <<< "$updl" ; else echo '지금은 없네요' ; fi"

Shell 을 띄우면(즉, 터미널을 열면) 아무 반응이 없거나, 갑자기 password 를 물어보거나 등등 바로 프롬프트가 떨어지질 않았다.

뭔가 문제가 있긴 한건데.. 과연 어디서 잘못한 걸까? 답은 ‘이스케이프’였는데, 특이하게도 $ 에도 해줘야 한다는 사실!

이게 답이다.

alias upg="updl=\$(sudo opkg list-upgradable | cut -f 1 -d ' ') ; if [[ \$(wc -l <<< \$updl) > 1 ]] ; then xargs sudo opkg upgrade <<< \"\$updl\" ; else echo '지금은 없네요' ; fi"

겹따옴표로 감쌌을 경우, 안에 있는 홑따옴표는 그냥 쓰면 된다. 즉, 이스케이핑을 할 필요가 없다. 괄호/대괄호도 그냥 쓴다. 겹따옴표는 당연히 이스케이핑 해야 하며, $도 마찬가지.

Bash 에서도 마찬가지겠지만, 적어도 Zsh 에서는 위 방법이 정답이었다.

지식의 보고 Stack overflow 에게 감사를.


참고로, 위 명령이 간단해보이지만, 내 리눅스 10년 내공이 만들어냈다고 해도 과언이 아니다. 좀 더 간단명료한 방법도 틀림없이 있겠지만.. 내가 지금 생각할 수 있는 방법은 저게 최선이다.

먼저, list-upgradable 이 0 보다 클 경우에만 작업을 하기 위해 if 가 필요했다. 그 내용은 여기서 참고했다. 사실 cut 을 여기서 할 필요는 없는데..

wc -l <<< $updlHere String 문법이다. 열심히 공부하고 정리해놓은 보람이 있네. (이 말 한마디 하고 싶어서 추가로 이 내용을 쓰게 됐네. 허허허)
사실, 저 방식대로 한다면 Here String 을 모르고는 진행이 어렵다. 파이프라인 만으로는 아마 구현이 어렵지 않을까 싶은데.. 그 근거로는 $(…) 로 처리되는 서브셸로 파이프라인이 잘 넘어갈까?? 라는 의문을 들 수 있다. 내가 시험해본 바로는, 넘어가질 않는다.)

xargs 뒤에도 역시 Here String 이 쓰였다. 처음엔 그냥 xargs 없이 sudo opkg upgrade <<< $updl 로만 작성했는데, 원하는대로 작동되지 않았다. man page 를 보니 이렇게 나와있다.

The specified command will be invoked as many times as necessary to use up the list of input items.

xargs 는, 인수(여기서는 $updl)가 목록으로 되어 있을 경우, 명령어(opkg upgrade)를 알아서 자동으로 그 숫자만큼 재실행되게끔 해주는 역할을 하는 모양이다.
간단하게 말해서 for loop 를 돌려주는 프로그램이라 생각하면 되겠다.

** 지금까진 그저 xargs 는 Pipeline 을 사용할 때는 그냥 써야만 하는 프로그램으로 생각했었다. 다시 말해서, 별 관심이 없었다.

좀 더 멋진 방법은 없으려나??

안녕하세요. 글 남겨주셔서 고맙습니다.