• 이전 문서: [[/mac/terminal-guide/05]]
  • 다음 문서: [[/mac/terminal-guide/07]]

echo로 확인하는 셸 확장

셸은 명령행으로 입력된 몇 가지 특수한 표현들을 확장하는 기능을 갖고 있습니다.

확장이 어떻게 작동하는지 살펴보는 가장 쉬운 방법은 echo 명령을 사용하는 것입니다.

중괄호 확장

중괄호가 포함된 명령이 어떻게 확장되는지 관찰해 봅시다.

$ echo {a,b,c}
a b c

$ echo {a,b,c}d
ad bd cd

이번에는 중괄호 안쪽에서 ..도 사용해 보겠습니다.

$ echo {1..8}
1 2 3 4 5 6 7 8

$ echo {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z

$ echo {A..z}
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [  ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z

물론 ..은 반대 방향으로도 작동합니다.

$ echo {8..1}
8 7 6 5 4 3 2 1

$ echo {100..90}
100 99 98 97 96 95 94 93 92 91 90

$ echo {z..a}
z y x w v u t s r q p o n m l k j i h g f e d c b a

$ echo {Z..A}
Z Y X W V U T S R Q P O N M L K J I H G F E D C B A

확장 문법은 셸의 명령어 전처리 기능이다

위에서 공부한 중괄호 확장을 사용한 명령 하나를 예로 들어 봅시다.

echo {a..c}

위의 명령을 실행하게 되면 마치 다음과 같이 [[/cmd/echo]]의 프로세스가 실행되고, 명령행 인자로는 {a..c}가 전달될 거라고 생각할 수 있습니다.

하지만 그렇지 않습니다. 셸은 [[/cmd/echo]]{echo}의 프로세스를 생성하기 전에 {a..c}를 읽고 a b c로 확장합니다.

그리고 나서 [[/cmd/echo]]{echo}의 프로세스를 생성하고, 명령행 인자로 a b c를 전달합니다.

이런 확장 문법은 [[/cmd/echo]]의 기능이 아닙니다. 셸에서 제공하는 거죠.

확장 기능을 셸에서 기본으로 제공하기 때문에 다음과 같은 이득이 있습니다.

  • 쓰는 사람 입장에서
    • 어떤 명령을 쓸 때에도 똑같은 확장 문법을 사용할 수 있습니다.
    • 한 번만 배워두면 계속 써먹으므로 효율 좋은 공부입니다.
    • 새로운 명령이 유행하게 되어도 확장 문법을 다시 배울 필요가 없습니다. 그냥 쓰던 걸 쓰면 됩니다.
    • 어떤 명령에서 확장이 되고, 안되고를 외울 필요가 없습니다.
  • 만드는 사람 입장에서
    • 명령을 만드는 사람들이 확장 기능을 직접 구현하지 않아도 됩니다.
    • 각 명령을 만드는 모든 사람들이 이것도 만들어야 했다면 엄청난 시간과 노력의 낭비가 되었을 것입니다.

규칙적인 나열이 좀 필요한 경우에는 일일이 타이핑하지 않고 확장 문법을 사용하는 것이 편리합니다. 실수할 가능성도 줄어들고요.

에를 들어 echo a b c d e f g h를 입력할 일이 있다면, 똑같은 구문으로 확장되는 echo {a..h}를 쓰면 됩니다.

연습: mkdir로 여러 디렉토리 한번에 만들기

위에서 배운 중괄호와 .. 확장 문법은 순열을 만들어내는 데 사용할 수 있어서, 많은 양의 규칙적인 데이터를 만들어내는 데 유용합니다.

다음 명령을 실행해 봅시다.

echo {2020..2023}-{0{1..9},1{0..2}}
$ echo {2020..2023}-{0{1..9},1{0..2}}
2020-01 2020-02 2020-03 2020-04 2020-05 2020-06 2020-07 2020-08 2020-09 2020-10 2020-11 2020-12 2021-01 2021-02 2021-03 2021-04 2021-05 2021-06 2021-07 2021-08 2021-09 2021-10 2021-11 2021-12 2022-01 2022-02 2022-03 2022-04 2022-05 2022-06 2022-07 2022-08 2022-09 2022-10 2022-11 2022-12 2023-01 2023-02 2023-03 2023-04 2023-05 2023-06 2023-07 2023-08 2023-09 2023-10 2023-11 2023-12

한 줄로 출력되어서 보기가 좀 어렵군요. [[/cmd/tr]]로 공백 문자(' ')를 줄바꿈 문자('\n')로 치환해보겠습니다.

$ echo {2020..2023}-{0{1..9},1{0..2}} | tr ' ' '\n'
2020-01
2020-02
2020-03
2020-04
2020-05
2020-06
2020-07
2020-08
2020-09
2020-10
2020-11
2020-12
2021-01
2021-02
2021-03
2021-04
2021-05
2021-06
2021-07
2021-08
2021-09
2021-10
2021-11
2021-12
2022-01
2022-02
2022-03
2022-04
2022-05
2022-06
2022-07
2022-08
2022-09
2022-10
2022-11
2022-12
2023-01
2023-02
2023-03
2023-04
2023-05
2023-06
2023-07
2023-08
2023-09
2023-10
2023-11
2023-12

{2020..2023}-{0{1..9},1{0..2}}는 2020년부터 2023년까지의 48개의 월로 확장된다는 것을 확인했습니다.

이제 이걸 사용해서 년-월 디렉토리를 만들어 봅시다. mkdir 명령을 사용하면 됩니다.

mkdir {2020..2023}-{0{1..9},1{0..2}}

mkdir 명령을 실행한 결과를 확인해 봅시다. [[/cmd/ls]]{ls}를 그냥 쓰면 한 줄로 나오니까 [[/cmd/xargs]]{xargs}로 한 줄에 5개씩 나오도록 출력해 보죠.

$ ls | xargs -n5
2020-01 2020-02 2020-03 2020-04 2020-05
2020-06 2020-07 2020-08 2020-09 2020-10
2020-11 2020-12 2021-01 2021-02 2021-03
2021-04 2021-05 2021-06 2021-07 2021-08
2021-09 2021-10 2021-11 2021-12 2022-01
2022-02 2022-03 2022-04 2022-05 2022-06
2022-07 2022-08 2022-09 2022-10 2022-11
2022-12 2023-01 2023-02 2023-03 2023-04
2023-05 2023-06 2023-07 2023-08 2023-09
2023-10 2023-11 2023-12

이렇게 만들어진 디렉토리의 수는 모두 48개입니다.

$ ls | wc -l
48

연습: rmdir로 여러 디렉토리 한번에 삭제하기

한꺼번에 수백만개의 파일을 분류해서 월별 백업용 디렉토리로 옮기는 작업을 한다면 쓸모가 있겠네요.

하지만 지금은 아니죠. 이제 이 디렉토리들을 삭제해 봅시다.

삭제하기 전에 새로운 확장 문법 *을 사용해 봅시다.

$ echo 2020-*
2020-01 2020-02 2020-03 2020-04 2020-05 2020-06 2020-07 2020-08 2020-09 2020-10 2020-11 2020-12

$ echo *-01
2020-01 2021-01 2022-01 2023-01

*을 쓰면 현재 작업 디렉토리에 있는 파일이나 하위 디렉토리의 이름 목록으로 확장됩니다.

20으로 시작하는 모든 디렉토리를 출력해 봅시다.

$ echo 20*
2020-01 2020-02 2020-03 2020-04 2020-05 2020-06 2020-07 2020-08 2020-09 2020-10 2020-11 2020-12 2021-01 2021-02 2021-03 2021-04 2021-05 2021-06 2021-07 2021-08 2021-09 2021-10 2021-11 2021-12 2022-01 2022-02 2022-03 2022-04 2022-05 2022-06 2022-07 2022-08 2022-09 2022-10 2022-11 2022-12 2023-01 2023-02 2023-03 2023-04 2023-05 2023-06 2023-07 2023-08 2023-09 2023-10 2023-11 2023-12

이번에는 20으로 시작하고 1로 끝나는 디렉토리를 출력해 봅시다.

$ echo 20*1
2020-01 2020-11 2021-01 2021-11 2022-01 2022-11 2023-01 2023-11

이제 이 디렉토리들을 삭제해 봅시다. 디렉토리를 삭제하는 rmdir 명령을 사용하면 됩니다.

rmdir은 디렉토리가 비어 있을 때만 삭제할 수 있습니다. 그래서 방금 생성한 디렉토리들 내에 파일을 복사해뒀다면 생각대로 작동하지 않을 수 있습니다.

rmdir * 로 모든 디렉토리 삭제하기

사실 남아있는 모든 디렉토리를 삭제하려면 그냥 rmdir * 하면 되긴 합니다.

rmdir *rmdir 2020-01 2020-02 2020-03 ... 처럼 남아있는 모든 디렉토리를 나열하는 방식으로 확장되기 때문입니다.

$ rmdir *

$ ls | wc -l
0

잘 삭제되었지만 좀 심심하군요.

rmdir -v 로 삭제된 디렉토리 로그 출력하기

다음 연습을 위해 방금 삭제한 빈 디렉토리들을 다시 만들어 봅시다.

mkdir {2020..2023}-{0{1..9},1{0..2}}

이번에는 각 해의 1월 디렉토리를 삭제해 봅시다.

rmdir-v 옵션을 주면 삭제된 디렉토리들의 이름을 출력해 줍니다.

$ rmdir -v *-01
2020-01
2021-01
2022-01
2023-01
  • 위의 명령은 rmdir -v 2020-01 2021-01 2022-01 2023-01로 확장된 다음에 실행됩니다.
    • 타이핑 횟수를 꽤 많이 줄일 수 있었네요.
  • 4개의 디렉토리가 삭제되었다는 것을 알 수 있습니다.

echo와 xargs 활용

이번에는 2월 디렉토리를 좀 다른 방법으로 삭제해 보죠.

$ echo *-02 | xargs rmdir -v
2020-02
2021-02
2022-02
2023-02
  • echo *-02: echo 2020-02 2021-02 2022-02 2023-02로 확장됩니다.
  • xargs rmdir -v: 파이프(|)를 통해 연결된 이전 명령의 출력을 이어받아 rmdir -v 명령을 실행합니다.

그냥 rmdir -v *-02를 실행해도 되는데 왜 굳이 앞에 echo를 붙여서 실행했을까요?

터미널에서 셸 명령을 입력할 때에는 책이나 강의와는 달리 실수하는 일도 흔하고, 명령을 단계별로 실행해보면서 결과를 확인하는 일이 많습니다.

그래서 삭제와 같이 되돌리기 어려운 명령을 실행하기 전에는 먼저 내가 의도한대로 작동할지를 따져보는 습관이 중요합니다.

즉 위의 방법은 삭제를 실행하기 전에 echo *-02로 삭제대상 목록을 먼저 확인해보고 나서, 이전에 성공한 명령을 위 화살표로 불러오고, 그 뒤에 | xargs rmdir -v를 붙여서 삭제를 실행한 것이라 할 수 있습니다.

$ # 내가 삭제하고 싶은 디렉토리들이 맞는지 확인
$ echo *-02
2020-02 2021-02 2022-02 2023-02

$ # 확인을 마쳤으니 ↑ 눌러서 이전 명령을 자동완성하고 뒤에 | xargs 추가
$ echo *-02 | xargs rmdir -v
2020-02
2021-02
2022-02
2023-02

이렇게 대상 목록을 확인한 다음, 그 결과를 다음 명령에 연결하기 위해 [[/cmd/xargs]]를 쓰는 경우가 많습니다.

동적 명령어 생성 후 bash로 넘겨 실행하기

이제 좀 더 까다로운 경우를 처리할 수 있는 실마리가 되는 방법을 알아봅시다.

지금까지 우리는 1월과 2월 디렉토리들을 삭제했습니다.

$ echo * | xargs -n5
2020-03 2020-04 2020-05 2020-06 2020-07
2020-08 2020-09 2020-10 2020-11 2020-12
2021-03 2021-04 2021-05 2021-06 2021-07
2021-08 2021-09 2021-10 2021-11 2021-12
2022-03 2022-04 2022-05 2022-06 2022-07
2022-08 2022-09 2022-10 2022-11 2022-12
2023-03 2023-04 2023-05 2023-06 2023-07
2023-08 2023-09 2023-10 2023-11 2023-12

확인해보니 3월부터 12월까지의 디렉토리들이 남아있네요.

이번에는 좀 색다른 방식으로 삭제해 보겠습니다. 다음과 같이 printf를 써서 rmdir 명령어를 사용하는 문자열을 출력만 해보면 어떨까요?

echo * | tr ' ' '\n' | xargs printf 'rmdir %s\n'

아마 이런 결과가 나올 것입니다.

$ echo * | tr ' ' '\n' | xargs printf 'rmdir %s\n'
rmdir 2020-03
rmdir 2020-04
rmdir 2020-05
rmdir 2020-06
rmdir 2020-07
rmdir 2020-08
rmdir 2020-09
... (생략) ...
rmdir 2023-12

문자열만 생성해서 printf로 출력만 했기 때문에 실제로 삭제되지는 않았습니다.

이제 이 결과를 bash로 파이프 연결을 하면…

$ echo * | tr ' ' '\n' | xargs printf 'rmdir %s\n' | bash

$ ls | wc -l
0

[[/cmd/bash]]가 xargs printf의 출력을 받아서 실행했기 때문에, 3월부터 12월까지의 디렉토리들이 삭제되었습니다.

이 트릭을 사용하면 동적으로 셸 스크립트를 생성하는 것과 다름없기 때문에 다양한 상황에서 응용할 수 있습니다.

*

이번에는 앞에서 사용해보았던 *에 대해 좀 더 알아봅시다.

*은 중괄호보다 더 많이 사용되는 확장 문법으로 '와일드카드', '아스테리스크', '스타', '별' 등으로 불립니다.

저는 그냥 MS-DOS를 사용하던 90년대에 '별'이라고 부르던 습관이 남아있어서 그냥 '별'이라고 부르곤 합니다.

bash 셸에 대해 잘 모르는 사람이더라도, 인터넷에서 복사해 온 명령을 터미널에서 실행한다던가 해서 *을 언뜻 사용해 본 적이 있을 수도 있습니다.

예를 들어 다음과 같은 것들이요.

ls *
ls *.txt

어떤 사람은 이 *이 정규표현식의 *일 거라고 생각하기도 하는데요, 셸의 문자열 확장 기호로서의 *은 정규표현식의 *과는 완전히 다른 의미와 역할을 갖고 있습니다.

정규표현식에서 *은 수량자입니다. 따라서 * 앞에 문자 클래스가 와야 합니다. 하지만 셸의 문자열 확장에서는 현재 디렉토리의 모든 파일과 디렉토리로 확장될 것을 표현하는 기호입니다.

즉 이것은 정규식이 아닙니다. glob 이라 부르는 파일/디렉토리 이름을 확장하기 위한 특수한 표현식입니다.

glob은 C 프로그래밍 언어의 라이브러리이기도 하므로 다음과 같이 [[/cmd/man]]{man 페이지}를 찾아 읽어볼 수도 있습니다.

man 3 glob

셸은 명령행을 통해 glob 문자를 제공받으면 이걸 파일/디렉토리들의 이름 목록으로 확장하는 것입니다.

실습을 위해 [[/cmd/touch]] 명령을 써서 다음과 같이 3개의 새로운 파일을 만들어 봅시다.

touch {a,b,c}.txt

그리고 나서 ls *.txt 명령을 입력해 봅시다.

$ touch {a,b,c}.txt

$ ls *.txt
a.txt  b.txt  c.txt

*.txt 패턴에 부합하는 a.txt, b.txt, c.txt 파일들이 출력되었습니다.

~

* 못지 않게 셸에서 자주 사용하는 것이 바로 ~입니다. '틸드'라고도 읽고 '물결'이라고도 읽는데, 저는 주로 '틸드'라고 읽습니다.

~는 홈 경로로 확장됩니다.

그래서 아무 명령 없이 ~만 입력하고 엔터를 치면…

$ ~
-bash: /Users/johngrib: is a directory

홈 경로로 확장된 다음 실행되려 하다가, 실행 가능한 명령이 아니라 그냥 디렉토리의 이름이기 때문에 에러가 출력됩니다.

그러니 아래와 같이 [[/cmd/echo]]를 써서 출력하는 것이 좀 더 보기 좋겠지요.

$ echo ~
/Users/johngrib

이런 것들은 한 명령에서 공존하는 것도 가능합니다.

$ echo ~ *
/Users/johngrib a.txt b.txt c.txt

만약 확장되는 게 싫다면 간단하게 따옴표로 감싸주면 됩니다.

$ echo '~' '*'
~ *

연습: rm -i 로 삭제하기 전에 확인하기

삭제같이 되돌리기 어려운 명령을 실행하기 전에는 다음과 같이 먼저 [[/cmd/echo]]나 [[/cmd/ls]]로 출력을 해보고 나서 실행하는 것이 좋은 습관입니다.

$ echo *.txt
a.txt b.txt c.txt

echo *a.txt, b.txt, c.txt가 출력되는 것을 확인했으니 이제 삭제를 해봅시다.

rm 명령은 삭제할 때 확인을 받지 않아 꽤 위험한 편입니다. 그러나 -i 옵션을 붙이면 컨펌을 받습니다.

$ rm -i *.txt
remove a.txt? y
remove b.txt? n
remove c.txt? y

$ ls *.txt
b.txt
  • rm -i: 삭제하기 전에 각 파일마다 정말로 삭제할건지 물어봅니다.

a.txtc.txt에는 y로 대답해서 삭제를 했고, b.txt에는 n으로 대답해서 삭제를 취소했습니다. 그 결과 b.txt는 남아있는 것을 확인할 수 있습니다.

좀 더 확실한 느낌을 받고 싶다면 -v 옵션도 추가할만 합니다.

$ touch {a..c}.txt

$ rm -iv *.txt
remove a.txt? y
a.txt
remove b.txt? y
b.txt
remove c.txt? n
  • rm -v: 파일을 삭제하면 삭제한 파일의 이름을 출력합니다.

저는 ~/.bashrc 파일에 다음과 같은 alias를 설정해 뒀습니다.

alias rm='rm -iv'

이렇게 alias를 적용하면 다음 셸을 열면서부터는 rmrm -iv로 치환됩니다.

그런데 질문은 몇 번 채널로 출력되고 있을까요? 궁금하니까 2번 채널을 null device로 연결해 보겠습니다.

$ touch {a..c}.txt
$ rm {a..c}.txt 2>/dev/null
y
a.txt
n
n

삭제 컨펌 질문이 보이지 않게 되었습니다.

$ rm -iv {a..c}.txt 2>confirm.txt
y
a.txt
y
b.txt
y
c.txt

$ cat confirm.txt
remove a.txt? remove b.txt? remove c.txt? 

rm 명령은 컨펌 질문을 2번 채널로 출력해서 보여주고 있었던 것입니다.

이런 질문들이 어느 채널로 출력되는지는 꼭 정해진 것이 아니라 명령마다 다릅니다. 어떤 명령은 2번 채널로, 어떤 명령은 /dev/tty로 질문을 출력합니다.

하지만 1번 채널, 즉 표준 출력으로 이런 질문을 남기는 일은 거의 없습니다. 1번 채널은 프로그램의 실행 결과를 정식으로 출력하는 채널이기 때문입니다. (그러나 이런 컨벤션을 모르는 사람이 개인적인 용도로 만드는 도구라면 질문을 할 때 그냥 System.out.println 같은 걸 사용해서 1번 채널로 할 수도 있겠죠)

rm을 만든 사람들의 경우는 질문 자체보다는 삭제된 파일의 이름 목록이 1번 채널에 더 어울린다고 생각했을 것입니다.

$ rm -iv {a..c}.txt 1>result.txt 2>confirm.txt
y
y
y

$ cat result.txt
a.txt
b.txt
c.txt

$ cat confirm.txt
remove a.txt? remove b.txt? remove c.txt? 

alias로 지정한 rm -i 를 우회하는 방법

alias rm='rm -iv'

위와 같이 rm에 대한 aliasrm -i를 사용하게 되면 많은 파일을 삭제할 일이 생겼을 때 일일이 y를 입력해야 하므로 불편합니다.

이에 대한 해결책도 알아봅시다.

간단한 방법: \로 alias escape 하기

명령 앞에 \를 붙이면 alias로 치환되지 않고 내가 입력한 명령이 그대로 실행됩니다.

\rm {a..c}.txt

위험한 방법: rm -f 사용하기

-f(force) 옵션을 붙이면 -i 옵션을 무시하고 강제로(force) 삭제해버립니다.

$ rm {a..c}.txt -f
a.txt
b.txt
c.txt

rm -f는 악명높은 명령입니다. 컨펌을 무시할 뿐만 아니라 각 파일의 권한도 무시하고, 없는 파일에 대한 삭제 명령을 내려도 종료상태값($?0입니다.

-f 옵션이 없는 rm은 다음과 같이 작동합니다.

$ # 파일이 없음
$ ls | wc -l
0

$ # 없는 파일을 삭제시켰으므로 경고가 출력된다
$ rm {a..c}.txt
rm: a.txt: No such file or directory
rm: b.txt: No such file or directory
rm: c.txt: No such file or directory

$ # 없는 파일을 삭제하려 했으므로 종료상태는 1 이다
$ echo $?
1

이번엔 rm -f가 어떻게 동작하나 확인해 봅시다.

$ rm {a..c}.txt -f

$ echo $?
0

없는 파일을 삭제하려 하는데도 경고도 없으며, 종료상태값도 정상 종료를 의미하는 0 입니다.

rm -rf 주의사항

rm -f는 주의깊게 다뤄야 하는 명령이며, 특히 디렉토리와 서브 디렉토리까지 한꺼번에 삭제하는 -r(recursive) 옵션까지 붙이면 더욱 주의해야 합니다.

sudo rm -rf / (이 명령은 절대 쓰지 마세요)는 root 경로부터 모든 파일을 삭제할 수 있습니다. 무서워서 시험해보지는 않았지만 아마도 내 컴퓨터의 하드디스크만 다 삭제하는 게 아니라 마운트된 디바이스 서브 트리 파일 시스템의 모든 파일도 삭제할 수 있습니다.

따라서 아주 오래된 버전의 rm이 아니라면 /에 대한 삭제를 차단하는 --preserve-root 옵션이 기본값으로 설정되어 있을 것입니다. 그러므로 실수 또는 장난으로 sudo rm -rf /를 입력해도 이 옵션이 막아줍…니다만…

문제는 macOS의 빌트인 rm은 버전이 낮아서 --preserve-root 옵션이 없다는 것입니다.

그러므로 저는 macOS의 빌트인 rm을 사용하지 않고 [[/cmd/gnu-coreutils]]의 rm을 설치해서 사용하고 있습니다.

저는 다음과 같이 GNU rm의 alias를 지정해 사용하고 있습니다.

alias "rm"="grm -i -v"

다음은 man grm에서 preserve-root 옵션을 검색한 결과입니다.

rm -f 를 조금 더 안전하게 사용하기

가급적 -f는 사용하지 않는 것이 바람직하지만 굳이 사용해야 한다면 옵션을 가장 뒤로 보내는 습관도 익혀둘만 합니다.

다음 두 명령은 똑같이 동작합니다.

rm -f a.txt b.txt
rm a.txt b.txt -f

-f를 마지막에 추가한다면 중간에 파일명을 나열하는 동안 실수로 엔터 키를 입력했을 때에도 -f 로 작동하지 않으므로 상대적으로 안전합니다.

이건 비슷한 파일 이름이 여럿 있는 경우에도 tab 키를 연타하며 부주의하게 명령을 입력할 때에도 미세하게 안전상 도움이 됩니다.

우아한 방법: yes 명령의 출력을 rm 으로 연결하기

[[/cmd/yes]]라는 특이한 명령이 있습니다. 이 명령을 실행하면 무한히 y를 출력합니다.

총력을 다해 y를 가장 빠르게 반복해서 출력하는 명령이므로, 그냥 실행하고 놔두면 얼마 지나지 않아 CPU 사용률 100%가 되는 것을 볼 수 있습니다.

그냥 yes를 실행하면 무한루프를 돌기 때문에 control c를 입력해서 종료해줘야 합니다.

$ yes | head
y
y
y
y
y
y
y
y
y
y

yeshead에 연결하면 10줄을 출력하고 나서 head가 종료되고, head가 종료되면서 입력채널이 닫히고, 그러면서 yes의 출력 채널도 닫히므로 yes의 프로세스도 순차적으로 종료됩니다.

이 명령은 반복시킬 문자열을 인자로 제공할 수도 있습니다.

$ yes 'hello world' | head -3
hello world
hello world
hello world

$ yes n | head -3
n
n
n

yes 명령을 rm -i와 조합해서 파이프라인을 만들면 일일이 y를 내 손으로 입력하지 않아도 yes 명령이 y 입력을 rm -i에 공급해줍니다.

$ touch {a..c}.txt

$ yes | \rm -iv {a..c}.txt
remove a.txt? a.txt
remove b.txt? b.txt
remove c.txt? c.txt

$ ls *.txt | wc -l
ls: *.txt: No such file or directory
0

yes가 공급한 3개의 yrm -i에 공급되어 모든 파일의 삭제에 대해 자동으로 컨펌이 진행되었습니다.

이전, 다음 문서

  • 이전 문서: [[/mac/terminal-guide/05]]
  • 다음 문서: [[/mac/terminal-guide/07]]