2010. 10. 27. 13:10

Ubuntu Shell 활용 (02) redirect / su, sudo / 환경 변수


Command Line Completion 사용하기

Tab키를 이용하여 command line을 완성키킬 수 있습니다.

$ tracer<Tab> : tracerout6 완성
$ cd /home/gre<Tab> : cd /home/greenfish/ 완성
$ cd ~gre<Tab> : cd /home/greenfish/ 완성
$ echo $PA<Tab> : echo $PATH 완성


stdin과 stdout으로 redirect하기

shell에서 typing하면 interactive하게 동작합니다. 결과를 보고하는 process는 두개의 output stream을 가집니다.
  • stdout : 일반 command의 output
  • stderr : error output

아래의 예로, /tmpp가 없는 경우, 에러 메시지는 stderr로 보내지고, /tmp의 list로 부터 나온 output은 stdout으로 출력됩니다.

$ ls /tmp /tmpp
ls: cannot access /tmpp: No such file or directory
/tmp:
orbit-gdm  pulse-PKdhtXMmr18n

기본적으로 모든 output은 스크린에 직접 표시됩니다. >문자를 사용하여 output을 파일로 저장할 수 있습니다. 특별히 standard output stream은 >를, standard error stream은 2>를 사용하여 파일로 저장합니다.
$ ls /tmp /tmmp > output.txt
ls: cannot access /tmmp: No such file or directory
$ ls /tmp /tmmp 2> errors.txt
/tmp:
orbit-gdm  pulse-PKdhtXMmr18n
$ ls /tmp /tmmp 2> errors.txt > ouptput.txt
$ ls /tmp /tmmp > everything.txt 2>&1

위 설명대로라면, 첫 예제는 output.txt에 stdout 내용이 저장(redirect)이 되며, stderr은 화면에 출력하게 됩니다. 두 번째 예제는 stderr은 errors.txt로 저장(redirect)되며, stdout은 화면에 출력됩니다. 세번째 예제는 첫 번째, 두 번째가 조합된 경우입니다. 그리고 마지막 예제는 두개 모두의 stream을 everything.txt에 저장(redirect)합니다. 만일 덮어 쓰기(overwrite) 대신에 파일에 추가하고 싶다면, >>를 사용합니다.

만약, 어떠한 output stream을 보고 싶지 않다면, 특별한 bit bucket 파일인 /dev/null로 redirect하여 해결할 수 있습니다.

$ ls /tmp
orbit-gdm  pulse-PKdhtXMmr18n
ls /tmp > /dev/null
$

다음은 pipe와 조합했을때의 경우입니다.
아래의 예에서는, stderr을 표시하지 않고, sort된 경로를 표시하는 방법을 보여줍니다.
$ ls /tmp/ /tmmp | sort
ls: cannot access /tmmp: No such file or directory
orbit-gdm
pulse-PKdhtXMmr18n
/tmp/:
$ ls /tmp/ /tmmp 2> /dev/null | sort
orbit-gdm
pulse-PKdhtXMmr18n
/tmp/:

$

또한 pipe는 다음과 같이 많은 것에 사용됩니다.
$ dpkg-query -l | grep -i sql | wc -l
3
$ ps auwx | grep firefox
1000      3136  0.0  0.1   3320   808 pts/6    S+   19:04   0:00 grep --color=auto firefox
$ ps auwx | less
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.3   2664  1608 ?        Ss   16:43   0:01 /sbin/init
...
:
...
$ whereis -m bash | awk '{print $2}'
/usr/share/man/man1/bash.1.gz

첫번째 명령은 설치된 package중에서 대소문자 구별없이 'sql'을 포함하는 것을 나열하되, 그 라인수를 출력하게 합니다. 두번째 명령은 long process 목록으로 부터 firefox process를 표시합니다. 세번째 명령은 process 목록을 페이지 단위로 보여줍니다. 마지막 명령은 "bash: /user/share/man/man1/bash.1.gz"와 같이 표시하는데, 단지 경로만 표시하도록 해줍니다.

`를 이용하여 한 section의 명령을 먼저 실행하고, 명령줄의 나머지 명령의 output을 입력(feed)합니다.
$ which bash
/bin/bash
$ ls -l /bin/bash
-rwxr-xr-x 1 root root 818232 2010-04-18 18:51 /bin/bash
$ ls -l `which bash`
-rwxr-xr-x 1 root root 818232 2010-04-18 18:51 /bin/bash
즉, 위 예처럼, which bash의 결과를 ls -l에 입력하여 실행이 됩니다.

좀더 결과를 입력하는 좀더 강력한 방법은 xargs command를 사용하는 것입니다.
$ ls /bin/b*
/bin/bash     /bin/bzcat   /bin/bzegrep  /bin/bzgrep        /bin/bzless
/bin/bunzip2  /bin/bzcmp   /bin/bzexe    /bin/bzip2         /bin/bzmore
/bin/busybox  /bin/bzdiff  /bin/bzfgrep  /bin/bzip2recover
$ dpkg-query -S /bin/bash
bash: /bin/bash
$ ls /bin/b* | xargs dpkg-query -S
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
$ 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
위 예에서, dpkg-query -S 명령으로 전달된 output을 전부 출력하고 있습니다. -t를 xargs에 사용하면, xargs를 사용하기 전의 output을 출력한뒤 실행합니다. 이제 dpkg-query 명령에 ls input으로 부터 output을 각각 xargs로 전달해 봅시다.
$ 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
bzip2: /bin/bzcat
dpkg-query -S /bin/bzcmp
bzip2: /bin/bzcmp
dpkg-query -S /bin/bzdiff
bzip2: /bin/bzdiff
dpkg-query -S /bin/bzegrep
bzip2: /bin/bzegrep
dpkg-query -S /bin/bzexe
bzip2: /bin/bzexe
dpkg-query -S /bin/bzfgrep
bzip2: /bin/bzfgrep
dpkg-query -S /bin/bzgrep
bzip2: /bin/bzgrep
dpkg-query -S /bin/bzip2
bzip2: /bin/bzip2
dpkg-query -S /bin/bzip2recover
bzip2: /bin/bzip2recover
dpkg-query -S /bin/bzless
bzip2: /bin/bzless
dpkg-query -S /bin/bzmore
bzip2: /bin/bzmore
output에서 보여진것 처럼, 각각의 dpkg-query -S 명령이 ls에 의해 실행된 것으로 각각 개별적으로 실행됩니다.


alias 사용하기

alias를 세팅하고 나열하는 것으로 alias를 사용합니다. 몇몇 alias들은 이전에 설명되었던 shell initialization 파일에 의해 사용자 지정된 경우 혹은 system-wide한 경우로 이미 세팅되어 있습니다.

$ alias
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'
alias ls='ls --color=auto'

확인해 볼 수 있는건, 이러한 alias들은 명령에 옵션을 추가할 수 있는 간순한 방법을 제공합니다.
$ alias la='ls -la'
alias
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l='ls -CF'
alias la='ls -la'
alias ll='ls -alF'
alias ls='ls --color=auto'
$ la
total 212
drwxr-xr-x 24 greenfish greenfish  4096 2010-10-18 18:27 .
drwxr-xr-x  3 root      root       4096 2010-09-30 16:34 ..
-rw-------  1 greenfish greenfish  9825 2010-10-18 19:50 .bash_history
-rw-r--r--  1 greenfish greenfish   220 2010-09-30 16:34 .bash_logout
-rw-r--r--  1 greenfish greenfish  3103 2010-09-30 16:34 .bashrc
drwx------  4 greenfish greenfish  4096 2010-10-03 20:28 .cache
drwxr-xr-x  6 greenfish greenfish  4096 2010-10-04 01:20 .config
...
$ unalias la
$ unalias -a
$ alias
$


Command Watch 하기

만약 command의 output을 계속 눈으로 보기 위한다면, watch 명령을 사용합니다. 아래를 통해 load average를 계속 눈으로 볼 수 있습니다.

$ watch 'cat /proc/loadavg'

Every 2.0s: cat /proc/loadavg                           Mon Oct 18 20:19:48 2010

0.06 0.06 0.00 1/176 3877

매 2초마다 해당 정보를 화면에 보여줍니다. ctrl+C를 통해 종료할 수 있으며, 갱신 기간을 10초로 하려면,
$ watch -n 10 'ls -l'
과 같이 하면 됩니다.

만약 변경된 부분을 highlight하고 싶다면, 아래를 참고하십시요.
$ watch -d 'ls -l'

아래와 같이 tail command로 ctrl+C를 누를 때 까지 파일을 계속 watch할 수도 있습니다.
$ sudo tail -f /var/log/message


Super user 권한 얻기

당신이 shell을 열면, 당신의 user/group ID와 권한을 기반으로 한 파일과 디렉토리를 접근하고 실행할 수 있습니다. 많은 system은 root user에 제약을 가하고 있습니다.
대략적으로 super user 권한을 얻기 위해서는 다음의 3가지 방법이 있습니다.
  1. root user로 로그인
  2. su 명령으로 임시적인 root user로 되기
  3. sudo 명령으로 root user 권한을 얻어 한번 실행하기

대부분의 경우, root user로 로그인할 필요는 없는데, 의도하지 않았던 변경사항으로 인한 사고를 방지하기 위함입니다. 대부분의 linux user는 일반 login에서 부터 root user로 변경하기 위해 su 명령을 사용하거나, root user로 실행해야 하는 단일 명령을 실행하기 위해 sudo 명령을 이용하기도 합니다.

Ubuntu에서는 sudo 명령으로 user를 추가할 수 있습니다. 대부분 관리자 권한 명령을 실행시킬 때 sudo 명령을 앞에 달아줘야 합니다. 예를 들면 $ sudo useradd -m joe 와 같습니다.

디폴트로, Ubuntu는 root user로 로그인을 하지 못하도록 제약을 걸고 있습니다. 그래서 su로 관리자 권한의 명령을 수행할 수 없습니다.

login as: root
root@xxx.xxx.xxx.xxx's password:
Access denied

$ su greenfish
Password:
$ exit
exit
$ su root
Password:
su: Authentication failure

만약 연속된 관리자 권한 명령 수행을 위해서는 아래와 같이 shell을 다시 띄우는 방법이 있습니다.
$ sudo bash
# ...
# exit
exit
$

그리고, sudo passwd root를 통해 root의 비밀번호를 변경할 수 있습니다.


sudo를 통한 권한 위임

이와 같이 sudo 명령은 user로 부터 root user로 권한을 위임하도록 해 줍니다. 또한 sudo는 많은 user를 관리할 때 특정 권한을 위임할 때 사용되는 도구이며, 이러한 권한으로 user의 모든 행위를 log해 줍니다.

아무런 옵션이 없는한 sudo는 root로 실행됩니다. Ubuntu linux는 특정 권한 명령을 수행하는데 사용되는데, su 명령보다 선호되는 방법입니다. sudo 명령은 /etc/sodoers에 설정되어 있습니다. (주의! 해당 파일은 필히 visudo로 편집해야 합니다)

/etc/sudoers 파일은 제한되어 있기때문에, sudo visudo를 통해 편집해야 합니다. 해당 명령은 nano editor를 통해 편집하도록 해 줍니다.

 GNU nano 2.2.2            File: /etc/sudoers.tmp

# /etc/sudoers
#
# This file MUST be edited with the 'visudo' command as root.
#
# See the man page for details on how to write a sudoers file.
#

Defaults        env_reset

# Host alias specification

# User alias specification

# Cmnd alias specification

# User privilege specification
root    ALL=(ALL) ALL

# Allow members of group sudo to execute any command after they have
# provided their password
# (Note that later entries override this, so you might need to move
# it further down)
%sudo ALL=(ALL) ALL
#
#includedir /etc/sudoers.d

# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL

^G Get Help  ^O WriteOut  ^R Read File ^Y Prev Page ^K Cut Text  ^C Cur Pos
^X Exit      ^J Justify   ^W Where Is  ^V Next Page ^U UnCut Text^T To Spell


root ALL=(ALL) ALL
이 있는데, 이는 모든 user가 모든 host에서 root로 됨을 허락한다는 뜻입니다.

%admin ALL=(ALL) ALL
은 admin group에 있는 모둔 user가 root로 됨을 허락한다는 뜻입니다.

Ubuntu linux를 설치하였다면, 당신이 추가한 user 계정은 자동으로 admin group에 추가됩니다. 추가된 user의 root 권한을 자동으로 하기 위해서는 다음과 같은 Line을 추가합니다.
USERNAME ALL= /usr/bin/less /var/log/messages

만약 USERNAME이 testacc였다면, 다음과 같은 것이 가능합니다.
$ sudo /usr/bin/less /var/log/messages
Password:
 
그럼, testacc의 비밀번호를 입력하면, /var/log/messages의 내용을 표시합니다.


환경 변수 사용하기

shell 환경에 사용되는 작은 양의 정보는 환경 변수에 저장됩니다. 규약에 따라 환경 변수는 대문자가 사용됩니다. 만약 bash을 사용한다면, 몇몇 환경 변수는 직전에 다뤘던 다양한 bash start scripts로 부터 세팅됩니다.

다음과 같이, 모든 환경 변수를 알파벳 순서로 표시할 수 있습니다.

$ set | less
BASH=/bin/bash
BASHOPTS=checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath
BASH_ALIASES=()
...

그리고 아래와 같이 환경 변수를 set/reset 할 수 있습니다.

$ echo $ABC

$ ABC=123
$ echo $ABC
123
$ bash
$ echo $ABC

$ exit
exit
$ echo $ABC
123


그리고, export에 의해 환경 변수를 child process에 상속할 수 있도록 할 수있습니다.

$ echo $ABC

$ export ABC=123
$ echo $ABC
123
$ bash
$ echo $ABC

123

'Research > Ubuntu' 카테고리의 다른 글

Ubuntu File Type 이해하기  (0) 2010.11.03
Ubuntu Shell 활용 (03) - 간단한 Bash shell script 작성하기  (0) 2010.10.29
Ubuntu Shell 활용 (01)  (0) 2010.10.21
APT 명령으로 관리하기  (0) 2010.10.15
ubuntu에서 man 활용하기  (0) 2010.10.07