echo ?, * 파일

unix and linux 2016. 12. 11. 01:08


유닉스 시스템에서 *는 모든 글자를 의미하고, ?은 한 단어를 의미한다.


특이하게도 cat a? 하면 a로 시작하고 2글자의 파일 이름을 가진 모든 파일을 의미하는데,


cat ?는 한 글자로 된 모든 파일 이름을 출력한다는 의미를 가진다. 



한 글자 파일이 없을 때 아래와 같은 에러가 발생한다.


$ cat ?

cat: ?: No such file or directory



한 글자 파일을 생성하고 cat ?을 실행해본다. 한 글자 파일을 출력한다.


$ cat > a

1

1

1


$ cat > b

2

2

2

2


$ cat ?

1

1

1

2

2

2

2


파일 명을 보고 싶다면, echo *을 실행한다.


$ echo ?

a b



2글자 이상의 파일명을 보려면 다음과 같이 실행한다.


$ echo ??*




참고로 *를 살펴본다.


echo * 커맨드를 실행하면 현재 디렉토리의 모든 이름을 출력한다. 중요한 것은 알파벳 순서대로 출력된다.


쉘은 *을 분석해 현재 디렉토리의 모든 파일을 검색해서 파일 이름 대체(filename substitution)하는 작업을 진행한다.  따라서 echo의 매개변수 개수는 1개가 아니라 현재 디렉토리의 파일 개수가 된다.



x=*의 값은 현재 디렉토리의 값이 된다. 


$ ls

AUTHORS                    LICENSE.txt-spymemcached   buildfile                  etc                        pom.xml                    xdocs

ChangeLog                  PATENTS                    devtools                   install-arcus-memcached.sh src

LICENSE                    README.md                  docs                       mvnTestConf.json


$ x=*


$ echo $x

AUTHORS ChangeLog LICENSE LICENSE.txt-spymemcached PATENTS README.md buildfile devtools docs etc install-arcus-memcached.sh mvnTestConf.json pom.xml src target xdocs



쉘이 커맨드 라인을 파악하는 단계는 다음과 같다. 

1. 쉘은 x 값으로 * 를 대체하여 라인을 스캔했다.

2. 쉘은 라인을 다시 살펴보고 * 를 발견 한 후 현재 디렉토리의 모든 파일 이름을 대체했다.

3. 쉘은 echo의 실행을 시작해 파일 목록을 매개변수로 전달했다.

(변수 대체를 먼저 진행하고 파일 대체를 진행한다)



grep에서 *를 사용할 때도 유의할 필요가 있다. 


특정 파일에서 '*'만 검색하려고 할 때  $ grep '*' file 을 사용할 수 있지만,


$ grep * file을 사용할 때 *는 현재 디렉토리의 모든 파일을 의미한다. 

아래 예시에서 의미를 파악할 수 있다. 


$ ls

Main$.class                 aZ

Main$delayedInit$body.class b

Main.class                  print_a.sh

Main.scala                  scalahello

a                           xx


$ grep * 123131

grep: 123131: No such file or directory

$ grep * xx

$ echo $?

1











참조 

https://en.wikipedia.org/wiki/Glob_(programming)

Posted by '김용환'
,


여러 java 데몬을 띄워 테스트를 진행하던 중, 자바 데몬에서 특정 포트(40000)를 리스닝하기 위해 실행 중에 아래와 같은 에러가 발생하고 종료되었다.


java.net.BindException: Address already in use


netstat으로 보면, 40000으로 분명 리스닝하는 포트가 없었다. 하지만, TIME_WAIT 클라이언트 포트가 있었다. 즉, 

 curl로 es schema를 생성하면서 40000번 포트를 사용했다. 


따라서, curl이 사용한 클라이언트 포트와 리스닝하려는 자바 데몬간의 충돌이 발생했다.


그렇다면, centos 6.7 기준으로 보면, curl이 사용한 포트 범위는 어떨까? sysctl 로 확인하면 클라이언트에서 사용할 수 있는 포트 범위는 32768부터 60999이다. 


$ sysctl -A | grep local_port_range

net.ipv4.ip_local_port_range = 32768 60999



따라서, 리스닝하는 포트를 쓰려면 32767 이전 포트를 사용하는 게 가장 안전하다.


Posted by '김용환'
,


ssh를 사용하여 리모트 파일이 존재하는 지 확인하려면, 다음과 같다.


already_copied=`ssh -l deploy s17.internal.io 'ls /tmp/test > /dev/null 2>&1' `

result=$?

if [ ${result} == 0 ]; then

  echo "file exists"

else

  echo "file does not exist"

fi



고급스럽게 사용하려면, ssh와 stat을 사용한다.




if ssh s17.internal.io stat /tmp/test \> /dev/null 2\>\&1

  then

    echo "file exists"

  else

    echo "file does not exist"

fi

Posted by '김용환'
,


jvm(일반 애플리케이션)이 실행 중인 서버에서 slab memory가 끊임없이 늘어나는 현상이 발견되었다.



* slab 메모리가 있는지 확인하기 위해 다음 링크를 참조하면 쉽게 slab 메모리 정보를 구할 수 있다. (/proc/meminfo에서 Slab 영역을 얻는다)

http://atomitech.jp/hinemos/blog/?cat=12


#!/bin/bash

total=`cat /proc/meminfo | grep MemTotal | awk '{print $2}'`
free=`cat /proc/meminfo | grep MemFree | awk '{print $2}'`
buff=`cat /proc/meminfo | grep Buffers | awk '{print $2}'`
cache=`cat /proc/meminfo | grep ^Cached | awk '{print $2}'`
slab=`cat /proc/meminfo | grep Slab | awk '{print $2}'`
used=`echo "scale=2; ($total - $free - $buff - $cache - $slab) * 100 / $total" | bc`
echo "used,$used"






참고로 jvm 메모리 상태를 확인하며 gc 여부를 확인했지만 특별히 변경 내역은 없었다.


$ jstat -gc 프로세스-id 1 1

 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT

 0.0   2048.0  0.0   2048.0 2383872.0 624640.0 1808384.0  1099923.5  61056.0 60410.3 7296.0 7135.3  32873  338.821   3      0.999  339.821

 



jvm은 이슈가 아닌 것 같고, vmstat으로 메모리 상태를 확인했다. 

각 필드의 항목 내용은 Num  Total   Size  Pages이다. 확실히 개수와 용량이 늘긴 늘었다

(vmstat 참고 : https://www.thomas-krenn.com/en/wiki/Linux_Performance_Measurements_using_vmstat#vmstat_-m)



$ vmstat -m  | grep proc_inode_cache

proc_inode_cache         4511372 4513830    656      6




다른 장비에서 동일한 명령어를 실행해서 동일하게 메모리를 확인했다. 


$ vmstat -m  | grep proc_inode_cache

proc_inode_cache          17500  17514    656      6




확실히 inode 캐시 값이 너무 커졌다. 이를 정리하기 위해 운영 체제의 vfs_cache_pressure를 사용해야 했다.



==============================================================

vfs_cache_pressure
------------------

This percentage value controls the tendency of the kernel to reclaim
the memory which is used for caching of directory and inode objects.

At the default value of vfs_cache_pressure=100 the kernel will attempt to
reclaim dentries and inodes at a "fair" rate with respect to pagecache and
swapcache reclaim.  Decreasing vfs_cache_pressure causes the kernel to prefer
to retain dentry and inode caches. When vfs_cache_pressure=0, the kernel will
never reclaim dentries and inodes due to memory pressure and this can easily
lead to out-of-memory conditions. Increasing vfs_cache_pressure beyond 100
causes the kernel to prefer to reclaim dentries and inodes.

Increasing vfs_cache_pressure significantly beyond 100 may have negative
performance impact. Reclaim code needs to take various locks to find freeable
directory and inode objects. With vfs_cache_pressure=1000, it will look for
ten times more freeable objects than there are.

 




jvm이 통신하면서 임시로 메모리 공간(pagecache)을 사용한 것 같은데, 정리가 안되면서 커진 것 같았다.  캐시 데이터는 centos 내부적으로 slab 메모리로 관리된다. inode가 커널의 slab 메모리에서 관리되기 때문에 inode와 slab 메모리가 상당히 커진 것 같았다. 


vfs_cache_pressure는 pagecache를 반환하려는 값이 저장되어 있다. 기본값은 100이다. 위의 문서에 설명되어 있듯이 0이면, 메모리 반환을 하지 않고, 1000을 설정하면 계속 free공간으로 메모리를 반환하려 한다.



나는 아래와 같이 값을 큰 값을 주어 자연스럽게 slab 메모리가 빨리 정리되게 했다. 


$ echo 10000 > /proc/sys/vm/vfs_cache_pressure



문제는 전혀 발생하지 않았고, slab 메모리를 깔끔히 정리되었다. 


이 외에 다른 방법이 있다고 한다. 



https://community.oracle.com/thread/3553285?start=0&tstart=0


To free pagecache: echo 1 > /proc/sys/vm/drop_caches

To free reclaimable slab objects (includes dentries and inodes): echo 2 > /proc/sys/vm/drop_caches

To free slab objects and pagecache: echo 3 > /proc/sys/vm/drop_caches





참고로 hbase에서는 이슈가 있었다고 하니. 부하가 높은 상황에서는 조심히 사용할 필요는 있을 것 같다. 


https://brunch.co.kr/@alden/14





Posted by '김용환'
,





커보러스 티켓 생성하기


$ kinit 계정명

#커보러스 티켓이 캐시에 저장 



커보러스 티켓 확인하기


$ klist

Ticket cache: FILE:/tmp/krb5cc_1000

Default principal:...


Valid starting       Expires              Service principal

...




티켓을 삭제하는 방법


$ kdestroy

klist: Credentials cache file '/tmp/krb5cc_1000' not found


Posted by '김용환'
,



centos의 git을 설치하면 (yum install git), 버전이 낮은 git이 설치된다. 따라서 git 명령어를 잘 인식 못할 수 있다.

현재는 yum install git으로 설치하면 2.2를 설치한다.



최신 git 을 설치하는 방법을 소개한다.



https://www.kernel.org/pub/software/scm/git/ 에 접속한다.


최신 버전을 찾는다. 현재는 2.9.3이 최신이다.



$ wget https://www.kernel.org/pub/software/scm/git/git-2.9.3.tar.gz

$ cd git-2.9.3

$ make prefix=/usr/local/git all

$ sudo make prefix=/usr/local/git install

$ echo "export PATH=$PATH:/usr/local/git/bin" >> ~/.bash_profile

$ source ~/.bash_profile


만약 root 사용자라면, ~/etc/bashrc를 수정한다.



Posted by '김용환'
,


공개키가 포함된 인증서와 개인 키를 생성하는 예제이다.

centos 7 부터 키 생성 방법이 엄청 편해졌다.

 


$ cd /etc/pki/tls/certs



$ sudo make server.crt



$ ls -al

..

-rw-------. 1 root root 1249  8월 16 13:18 server.crt

-rw-------. 1 root root 1766  8월 16 13:18 server.key



키가 정상적인 지 확인하려면, 다음 커맨드를 실행해서 공개 키와 개인 키를 기반으로 나온 결과 값이 동일한지 확인한다.



$ sudo openssl x509 -noout -modulus -in server.crt | openssl md5

(stdin)= 797c0391f368bde47394aac7adf5bcdb




$ sudo openssl rsa -noout -modulus -in server.key | openssl md5

Enter pass phrase for server.key:

(stdin)= 797c0391f368bde47394aac7adf5bcdb




Posted by '김용환'
,



ssh 연결시 다음 에러가 발생했다.


Host key verification failed.



ssh 인증시. 에러가 발생했고, 이를 해결하기 위해 ssh -v를 실행했다. 로그가 자세히 출력되고 힌트를 얻을 수 있다.



debug1: read_passphrase: can't open /dev/tty: No such device or address

Host key verification failed.




ssh -o StrictHostKeyChecking=no 추가하면 문제 없이 로그인할 수 있다. 





Posted by '김용환'
,

yum 캐시 데이터로 인해서 잘못된 동작이 일어날 수 있다. 이럴 때, yum의 캐시를 정리할 수 있다.



캐시된 패키지 정보를 모두 삭제하는 커맨드이다.


$ sudo yum clean packages



캐시된 XML 기반의 메타데이터를 삭제한다.


$ sudo yum clean metadata



캐시된 모든 데이터베이스 파일을 삭제한다.


$ sudo yum clean dbcache



사용하지 않는 불필요한 디스크 공간을 정리하고, 동시에 이전 커맨드와 같이 캐시된 모든 파일을 삭제한다.


$ sudo yum clean all



다음 커맨드를 실행하여 yum 캐시를 재구성한다.


$ sudo yum makecache



Posted by '김용환'
,



저널 로그를 보려면 다음과 같다. 센트OS 7의 시스템 서비스의 대부분은 저널 로그에 저장된다.


$ sudo journalctl



기간별 검색이 가능하다.


$ sudo journalctl --since "2016-08-06 00:00:00" --until "2016-08-10 10:30:00"

-- Logs begin at 금 2016-08-05 00:17:04 KST, end at 월 2016-08-08 11:34:27 KST. --

 8월 06 00:00:01 kara070 CROND[12476]:




어제부터 sshd.service 로그를 보고 싶다.


$ sudo journalctl -u sshd.service --since "yesterday"

-- Logs begin at 금 2016-08-05 00:17:04 KST, end at 월 2016-08-08 11:35:02 KST. --

...





에러 타입에 대한 저널 로그를 살펴본다.


$ sudo journalctl -p err -b



상세로그를 보려면 다음을 실행한다.


$ sudo journalctl -p err -b -o verbose



상세로그를 tail -f 처럼 보고 싶을 때 다음처럼 실행한다.


$ sudo journalctl -f




참고로, 도커 설정 파일에도 다음과 같은이 저널 로그를 설정되어 있다.


OPTIONS='--selinux-enabled --log-driver=journald'



Posted by '김용환'
,