Linux Shell Redirection, pipe, xargs

원본링크

■ 리다이렉션(Redirection)
명령이 실행되기에 앞서 쉘에 의해 특별하게 해석되는 표시를 사용하여 입력과 출력을 방향 전환 또는 리다이렉트 할 수 있다.

stdin 키보드 (표준입력, 0)
stdout 모니터 (표준출력, 1)
stderr 모니터 (에러출력, 2)
> 출력 리다이렉션 (stdout 만을 보냄)
< 입력 리다이렉션 (stdin 파일로부터 데이터를 받음)
>> 추가 출력 리다이렉션 (새로 덮어쓰지 않고 추가)
2> 표준에러 리다이렉션 (stderr 만을 보냄)
&>word
>& word
>word 2>&1
표준 출력과 표준에러를 동시에 리다이렉트 함

 

표준출력은 파일 output.txt로 리다이렉트

$ ls /tmp /tmmp > output.txt
ls: /tmmp에 접근할 수 없습니다.: 그런 파일이나 디렉터리가 없습니다

반대로 표준에러를 error.txt 파일에 리다이렉트.(표준출력은 그대로 화면 출력)

$ ls /tmp /tmmp 2> errors.txt
/tmp:
keyring-QC9vEx pulse-2L9K88eMlGn7 rsync_1007
orbit-devanix pulse-PKdhtXMmr18n ssh-jbzyRBjE1162

앞의 두 예제를 합쳐놓은 것.

$ ls /tmp /tmmp 2> errors.txt > output.txt
/* cat으로 errors.txt 와 output.txt 출력 */
$ cat errors.txt
ls: /tmmp에 접근할 수 없습니다.: 그런 파일이나 디렉터리가 없습니다
$ cat output.txt
/tmp:
keyring-QC9vEx
orbit-devanix
pulse-2L9K88eMlGn7
pulse-PKdhtXMmr18n
rsync_1007
ssh-jbzyRBjE1162

두 스트림(stdout, stderr) 출력을 모두 everything.txt 파일에 쓰도록 함.

$ ls /tmp /tmmp > everything.txt 2>&1
/* cat으로 everything.txt 출력 */
$ cat everything.txt
ls: /tmmp에 접근할 수 없습니다.: 그런 파일이나 디렉터리가 없습니다
/tmp:
keyring-QC9vEx
orbit-devanix
pulse-2L9K88eMlGn7
pulse-PKdhtXMmr18n
rsync_1007
ssh-jbzyRBjE1162

두 개의 그레이터 댄(>>) : 새로 덮어쓰지 않고 추가 되도록 하기

$ ls /tmp >> output.txt

에러 출력을 화면에 출력 하지 않기 (비트버킷 파일(/dev/null) 보내기)

$ ls /tmp /tmmp 2> /dev/null
/tmp:
keyring-QC9vEx pulse-2L9K88eMlGn7 rsync_1007
orbit-devanix pulse-PKdhtXMmr18n ssh-jbzyRBjE1162

/etc/hosts 파일을 mail 명령어의 표준 입력 스트림으로 보내기

$ mail chris < /etc/hosts

 

 

■ 파이프( | )를 사용
하나의 프로세스 출력을 파일이 아닌 다른 프로세스로 리다이렉트.

ls명령의 표준출력이 파이프를 통해 sort 명령어로 보내져 실행결과가 정렬되어 출력.

$ ls /tmp | sort

파이프 리다이렉션을 조합하여 ls 명령어의 표준출력은 정렬되고 에러출력은 비트버킷(/dev/null)으로 비운다.

$ ls /tmp /tmmp 2> /dev/null | sort

그밖에 다양한 활용.

/* 설치되어 있는 모든 패키지 에서 sql 문자열이 포함되어 있는 패키지 개수 */

$ dpkg-query -l | grep -i sql | wc -l

/* Firefox 문자를 포함하고 있는 프로세스 출력 */

$ ps auwx | grep firefox

/* 프로세스 목록 한 화면씩 출력 */

$ ps auwx | less

/* 순수하게 맨 페이지 경로만을 출력 */

$ whereis -m bash | awk \'{print $2}\'

■ 작은 인용부호( )를 사용
인용부호로 묶인 명령어의 실행결과를 나머지 명령어의 입력으로 사용
/* ps 명령어의 전체경로를 찾은 후에 이 명령어를 포함하고 있는 패키지를 찾음 /
<pre>$ dpkg-query -S
which ps→ dpkg-query -S /bin/ps</pre>
/ bash 명령어의 전체경로를 찾아 해당 명령어의 상세 목록을 보여줌 */
<pre>$ ls -l
which bash→ ls -l /bin/bash</pre>
작은 인용부호(
)는 키보드 느낌표(!) 왼쪽에 있음.

■ xargs명령을 이용
하나의 명령의 실행결과를 다른 명령어의 인자로 넘겨주기

ls명령의 /bin/b*의 실행결과는 dpkg-qeury -S 명령어의 인자로 전달

$ ls /bin/b* | xargs -t dpkg-query -S
dpkg-query -S /bin/bash /bin/bunzip2 /bin/busybox /bin/bzcat /bin/bzcmp /bin/bzdiff /bin/bzegrep /bin/bzexe /bin/bzfgrep /bin/bzgrep /bin/bzip2 /bin/bzip2recover /bin/bzless /bin/bzmore
bash: /bin/bash
bzip2: /bin/bunzip2
busybox-static: /bin/busybox
bzip2: /bin/bzcat
bzip2: /bin/bzcmp
bzip2: /bin/bzdiff
bzip2: /bin/bzegrep
bzip2: /bin/bzexe
bzip2: /bin/bzfgrep
bzip2: /bin/bzgrep
bzip2: /bin/bzip2
bzip2: /bin/bzip2recover
bzip2: /bin/bzless
bzip2: /bin/bzmore

-t 옵션을 적용하면 명령어 실행시 화면에 좀 더 상세한 정보가 출력.
-I{}를 이용하여 ls명령이 출력하는 각 문자열을 하나씩 dpkg-query 명령어의 입력으로 보냄.

$ ls /bin/b* | xargs -t -I{} dpkg-query -S {}
dpkg-query -S /bin/bash
bash: /bin/bash
dpkg-query -S /bin/bunzip2
bzip2: /bin/bunzip2
dpkg-query -S /bin/busybox
busybox-static: /bin/busybox
dpkg-query -S /bin/bzcat
…[중략]…

실행결과에서 볼 수 있듯이 dpkg-query -S 명령어는 ls로부터 인자로 전달된 각 개별 문자열을 사용해 반복적으로 실행.

※ 맨 페이지(man page) 참조 : man bash, man xargs

Change Bash Custom Prompt

http://www.cyberciti.biz/tips/howto-linux-unix-bash-shell-setup-prompt.html

 

Prompt is control via a special shell variable. You need to set PS1, PS2, PS3 and PS4 variable. If set, the value is executed as a command prior to issuing each primary prompt.

  • PS1 – The value of this parameter is expanded (see PROMPTING below) and used as the primary prompt string. The default value is s-v$ .
  • PS2 – The value of this parameter is expanded as with PS1 and used as the secondary prompt string. The default is >
  • PS3 – The value of this parameter is used as the prompt for the select command
  • PS4 – The value of this parameter is expanded as with PS1 and the value is printed before each command bash displays during an execution trace. The first character of PS4 is replicated multiple times, as necessary, to indicate multiple levels of indirection. The default is +

How do I display current prompt setting?

Simply use echo command, enter:
$ echo $PS1
Output:

\\[email protected] \\W]\\$

How do I modify or change the prompt?

Modifying the prompt is easy task. Just assign a new value to PS1 and hit enter key:
My old prompt –> [[email protected] ~]$
PS1=\"touch me : \"
Output: My new prompt

touch me :

So when executing interactively, bash displays the primary prompt PS1 when it is ready to read a command, and the secondary prompt PS2 when it needs more input to complete a command. Bash allows these prompt strings to be customized by inserting a number of backslash-escaped special characters that are decoded as follows:

  • a : an ASCII bell character (07)
  • d : the date in \”Weekday Month Date\” format (e.g., \”Tue May 26\”)
  • D{format} : the format is passed to strftime(3) and the result is inserted into the prompt string; an empty format results in a locale-specific time representation. The braces are required
  • e : an ASCII escape character (033)
  • h : the hostname up to the first \’.\’
  • H : the hostname
  • j : the number of jobs currently managed by the shell
  • l : the basename of the shell’s terminal device name
  • n : newline
  • r : carriage return
  • s : the name of the shell, the basename of $0 (the portion following the final slash)
  • t : the current time in 24-hour HH:MM:SS format
  • T : the current time in 12-hour HH:MM:SS format
  • @ : the current time in 12-hour am/pm format
  • A : the current time in 24-hour HH:MM format
  • u : the username of the current user
  • v : the version of bash (e.g., 2.00)
  • V : the release of bash, version + patch level (e.g., 2.00.0)
  • w : the current working directory, with $HOME abbreviated with a tilde
  • W : the basename of the current working directory, with $HOME abbreviated with a tilde
  • ! : the history number of this command
  • # : the command number of this command
  • $ : if the effective UID is 0, a #, otherwise a $
  • nnn : the character corresponding to the octal number nnn
  • \\ : a backslash
  • [ : begin a sequence of non-printing characters, which could be used to embed a terminal control sequence into the prompt
  • ] : end a sequence of non-printing characters

Let us try to set the prompt so that it can display today’d date and hostname:
PS1=\"d h $ \"
Output:

Sat Jun 02 server $

Now setup prompt to display date/time, hostname and current directory:
PS1=\"[d t [email protected]:w ] $ \"
Output:

[Sat Jun 02 14:24:12 [email protected]:~ ] $