# dir_a 디렉토리 자체를 copy_a 안에 복사함
cp -rv "~/dir_a" "~/copy_a"
# dir_a 안의 파일, 서브디렉토리 모두 copy_a 로 복사. 단 숨김 파일/디렉토리는 복사 X
cp -rv "~/dir_a/*" "~/copy_a"
# dir_a 안의 파일, 서브디렉토리 모두 copy_a 로 복사 + 숨김 파일/디렉토리도 모두 복사
cp -rv "~/dir_a/." "~/copy_a"
rsync -av --exclude='node_modules' /mnt/c/frontend/ frontend
# /mnt/c/frontend/ 라는 외부 디렉토리의 내용을 모두 현재 경로의 frontend 디렉토리 안으로 옮긴다.
# rsync 에서 {복사 source} 에 대해서 끝에 "/" 를 붙이면 내부의 모든 파일을 가져오고,
# "/" 이 없으면 디렉토리를 통으로 가져옵니다. 주의하세요.
# 현재 디렉토리에서 java 파일을 재귀적으로 찾아냄
find "${PWD}" -type f -name "*.java"
# 현재 디렉토리에서 bck 디렉토리를 재귀적으로 찾아냄
find "${PWD}" -type d -name "*bck"
# "-maxdepth 1" 처럼 옵션을 줘서 재귀 depth 지정 가능
# 여러 파일 확장자 기준으로 검색
find . -type f \( -name "*.java" -o -name "*.xml" -o -name "*.yaml" \)
# 내용 복사 (trailing slash 중요!)
rsync -av ./source/frontend/frontend/ ./source/frontend/
# 원본 폴더 삭제
rm -rf ./source/frontend/frontend
find . -type f -exec chmod 644 {} + # 모든 파일의 file permission 변경
find . -type d -exec chmod 755 {} + # 모든 디렉토리의 file permission 변경
# find "${PWD}" ~~ 처럼해도 좋음
참고
-exec 명령어 {} \;= 파일 하나씩 실행 (느림)
-exec 명령어 {} += 파일 여러 개 묶어서 실행 (빠름)# \; 사용 - 각 파일마다 개별 실행 find . -type f -name "*.txt" -exec echo "Processing:" {} \; # 출력: # Processing: file1.txt # Processing: file2.txt # Processing: file3.txt # + 사용 - 한 번에 실행 find . -type f -name "*.txt" -exec echo "Processing:" {} + # 출력: # Processing: file1.txt file2.txt file3.txt
# 일단 파일이 있는지 조회
ls ~/.ssh/id_rsa*
# 만약 위에서 조회됐다면 이 과정은 생략
ssh-keygen -t rsa
# 공개키 전송하여 원격서버 .ssh/authorized_keys 에 등록
ssh-copy-id 원격서버_계정@원격서버_HOST
# 이후에 비번없이 로그인
ssh 원격서버_계정@원격서버_HOST
# 참고: 만약에 AWS pem key 사용이면?
ssh -i "${PEM_KEY_경로}" 원격서버_계정@원격서버_HOST
# 꼭 pem 키가 이나더라도, client 단의 개인키가 .ssh/id_rsa 가 아니면
# 로그인할 때 -i 옵션을 줘야 한다.
참고하면 좋은 글 : SSH 공개키 인증을 사용하여 접속하기
touch ~/.ssh/config # 파일이 없다면 생성
chmod 600 ~/.ssh/config # 보안을 위한 file permission 변경
# 이후에 파일에 아래처럼 입력
vim ~/.ssh/config
내용은 아래와 같은 패턴으로 작성하면 된다.
Host server-alias
HostName 10.0.0.10
User dailycode
Port 2222
IdentityFile ~/.ssh/id_rsa_company
Host : 별칭, 와일드 카드 사용 가능HostName : 실제 원격서버 IP 혹은 도메인 명(ex: naver.com) User : 접속 계정 명Port : ssh 연결 포트IdentityFile : ssh client 의 개인키 경로그외에도
ServerAliveInterval :
연결 유지를 위해서 ssh 서버로 몇초마다 신호를 보낼지 지정
기본적으로는 0
ServerAliveCountMax:
만약에 신호를 보내게 되면 재시도 횟수를 얼마나 할지를 지정
기본으로 3. ServerAliveInterval 와 함께 사용했을 때 효력이 있음.
# tar.gz로 압축
# 참고로 압축 결과물과 압축 대상 디렉토리가 같은 위치면
# tar.gz 압축 안에 tar.gz 가 들어가니 주의 바란다.
# 압축 결과물이 압축 대상 디렉토리와 겹치지 않도록 하자.
tar -czf ../archive.tar.gz .
# 아니면 특정 디렉토리를 그냥 통으로 압축하는 것도 좋다.
tar -cvf archive.tar.gz {디렉토리 명}
# 디렉토리 명칭이 아닌 디렉토리 전체 경로를 사용해야 될때는 아래처럼.
# -C 는 cd 를 해서 해당 경로로 이동한다는 의미다.
tar -cvf archive.tar.gz -C {디렉토리_경로} .
# 압축된 내용(목록) 확인
tar -tvf archive.tar.gz
# 특정 디렉토리/파일 제외하면서 압축
tar -czf archive.tar.gz --exclude='*.log' {디렉토리 명}
# timestamp suffix 주기
tar -czf archive_$(date +%Y%m%d_%H%M%S).tar.gz {디렉토리 명}
# 압축 해제
tar -xzf archive.tar.gz
# zip 파일 압축
zip -r $(basename $PWD)_$(date +%Y%m%d_%H%M%S).zip .
# 몇가지 제외시키면서 압축하기
# 아래 예시는 .claude 디렉토리와 *.log 파일들 모두 제외하면서 압축하는 것
zip -r \
$(basename $PWD)_$(date +%Y%m%d_%H%M%S).zip . -x ".claude/*" -x "*.log"
# 압축 해제
unzip archive.zip -d /path/to/destination/
# 참고: 내용만 확인
# unzip -l archive.zip
# 자기자신의 비번 변경
passwd
# 다른 사용자 비번 변경
sudo passwd linux
# 방법1
grep -c '<NAME>' *EMPLOYEE_INFO_*.xml
# 여러 단어면?
grep -cE '<NAME>|<ADDRESS>' *EMPLOYEE_INFO_*.xml
# 방법2
cat *.xml | grep -c "<row>"
## 주석 처리
1. "ctrl + v" 를 입력
2. "j"(아래), "k"(위) 를 입력해서 영역 지정
3. ":" 입력
4. 이후에 ":'<,'>" 처럼 입력란이 나오면, 그 상태에서
한칸 띄고 " norm i#" 를 입력한다.
전체적으로 ":'<,'> norm i#" 처럼 보이게 된다.
## 주석 해제
1. 주석처리의 1~3 번 과정은 모두 똑같다.
2. 이후에 ":'<,'>" 처럼 입력란이 나오면, 그 상태에서
한칸 띄고 " norm 1x" 를 입력한다.
전체적으로 ":'<,'> norm 1x" 처럼 보이게 된다.
참고로 "1x" 는 맨앞의 한 개의 문자열을 지우겠다는 의미다.
redo : ctrl + r
undo : u
문단 단위 밑으로 이동: shift + ]
문단 단위 위로 이동: shift + [
문서의 맨 위로 이동 : gg
문서의 맨 끝으로 이동 : GG
한줄의 맨 앞으로 이동 : shift + ^
한줄의 맨 뒤으로 이동 : shift + $
단어 단위(특수문자도 단어로 인식)로 앞으로 이동: w
단어 단위(특수문자도 단어로 인식)로 뒤로 이동: b
단어 단위(공백으로만 구분)로 앞으로 이동: ctrl + w
단어 단위(공백으로만 구분)로 뒤로 이동: ctrl + b
검색해서 이동: "/" 입력후 검색어 입력 + Enter,
이후에 계속 이어서 검색하려면 "n"(밑으로 검색) 입력
또는 "N"(위로 검색) 입력
특정 라인 넘버로 이동:
- 먼저 라인 번호가 나오게 ":" 입력후, "set number" 라고 입력
- 이후 ":" 입력후 라인 번호(숫자) 입력 후 Enter
:set nowrap
참고로 crontab 은 각각의 사용자가 개별적으로 예약하는 시스템이기 때문에
내가 지금 사용하는 계정으로 crontab 을 작성하면,
다른 사용자 눈에는 crontab 작성 내역이 보이지 않습니다.
crontab -e
아래와 같은 화면이 나옵니다.

맨 밑에 자신이 시간에 동작하도록 작성합니다.
참고로 cron 표현식의 최소 단위는 초가 아니라 분입니다.
# 매일 오전 11시에 app.jar 를 실행한다.
0 11 * * * /usr/bin/java -jar /app/app.jar
다시 해당 예약을 지우려면 crontab -e 입력 후 작성한 line 을 제거하면 됩니다.
만약에 그냥 crontab 파일 자체를 지우고 싶으면 crontab -r 을 수행하세요.
crontab -l
grep CRON /var/log/syslog

crontab 을 통해서 쉘 스크립트나 명령어를 실행할 때 조금 조심할 부분이 있습니다.
예를 들어서 crontab 으로 java 명령어를 사용한다고 가정해보겠습니다.
* * * * * java --version >> /tmp/some.log 2>&1
이러면 some.log 파일에는 다음과 같은 로그를 띄울 수도 있습니다.
/bin/sh: 1: java: not found
/bin/sh: 1: java: not found
/bin/sh: 1: java: not found
이러는 이유는 cron 은 일반적으로 명령어를 찾는 PATH 가 /usr/bin:/bin 정도로
제한되어 있어서 그렇습니다. 저의 경우에는 java 바이너리가 /usr/bin
또는 /bin 에 없어서 저렇게 나오는 겁니다.
그러니 확신이 안 들때는 반드시 실행 명령어의 절대 경로를 작성하는 게 좋습니다.
# 저는 sdkman 으로 java 를 설치해서 경로가 다음과 같습니다.
* * * * * /home/toastbread/.sdkman/candidates/java/current/bin/java --version >> /tmp/some.log 2>&1
만약에 crontab 이 사용하는 PATH 를 확인하고 싶으면 다음처럼 확인이 가능합니다.
* * * * * env > /tmp/env_state.log
