원 글 : https://zeouscik.tistory.com/208
Shell Tools and Scripting
shell scripting 중략.. 다음에 bash scripting 필요해지면 보기
shebang
파일 찾기
예를 들어 fd는find에 대한 간단하고 빠른 사용자 친화적 대안입니다. fd는 색상화된 출력, 기본 정규식 일치 및 유니 코드 지원과 같은 멋진 기본값을 제공합니다. 또한 제 생각에는 보다 직관적인 것 같습니다. 예를 들어 패턴 PATTERN을 찾는 구문은 fd PATTERN입니다.
구문 찾기 grep
그러나 grep -R은 다중 CPU 지원, & c를 사용하여.git 폴더를 무시하는 등 여러가지 방법으로 개선할 수 있습니다. ack, ag 및 rg를 포함한 많은 것들이 grep의 대안으로 개발되었습니다. grep의 대안으로 나온 저 모든 것들은 환상적이며 거의 동일한 기능을 제공합니다. 지금은 얼마나 빠르고 직관적인지를 고려할 때 ripgrep(rg)를 사용하고 있습니다.
내가 정말 좋아하는 또 다른 멋진 기록 관련 트릭은 기록 기반 자동 제안 입니다. fish 셸에서 처음 도입된 이 기능은 공통 접두사를 공유하는 가장 최근에 입력한 명령으로 현재 셸 명령을 동적으로 자동 완성합니다. zsh에서 활성화 할 수 있으며 셸을 사용하는데 엄청난 도움이 됩니다.
Directory Navigation
Finding frequent and/or recent files and directories can be done through tools like fasd and autojump.
Comamnd-line Environment
Your shell is using a UNIX communication mechanism called a signal to communicate information to the process. When a process receives a signal it stops its execution, deals with the signal and potentially changes the flow of execution based on the information that the signal delivered. For this reason, signals are software interrupts.
How should you organize your dotfiles? They should be in their own folder, under version control, and symlinked into place using a script. This has the benefits of:
Easy installation: if you log in to a new machine, applying your customizations will only take a minute.
Portability: your tools will work the same way everywhere.
Synchronization: you can update your dotfiles anywhere and keep them all in sync.
Change tracking: you’re probably going to be maintaining your dotfiles for your entire programming career, and version history is nice to have for long-lived projects.
Dotfile
SSH
zsh, oy-my-zsh
kitty (GPU 가속화)
당신의 shell은 신호 라고 불리는 UNIX 통신 메커니즘을 사용하여 정보를 프로세스에 전달하고 있습니다. 프로세스가 실행을 중지하는 신호를 수신하면 해당 신호를 처리하고, 신호가 전달한 정보를 기반으로 실행 흐름을 잠재적으로 변화시킵니다.
터미널에서 Ctrl-Z를 입력하면 shell이 Terminal Stop(터미널 버전 SIGSTOP)을 줄인 SIGTSTP 신호를 보냅니다.
그 다음 각각 fg 또는 bg 를 사용하여 포어그라운드 또는 백그라운드에서 일시 중지된 작업을 계속할 수 있습니다.
jobs 명령어에는 현재 터미널 세션과 관련된 미완료 작업 목록을 보여줍니다. 목록의 pid(pgrep 사용)를 이용하여 해당 작업을 참조할 수 있습니다. 이미 실행 중인 프로그램을 백그라운드 실행으로 변경하려면 Ctrl-Z에 이어 bg를 실행하면 됩니다. 백그라운드 프로세스는 여전히 터미널의 하위 프로세스로서 터미널을 닫으면 죽는다는 점에 유의하세요 (또 다른 신호인 SIGHUP를 전송).
도트 파일을 통해 구성할 수 있는 도구의 다른 예는 다음과 같습니다 :
bash - ~/.bashrc, ~/.bash_profile
git - ~/.gitconfig
vim - ~/.vimrc and the ~/.vim folder
ssh - ~/.ssh/config
tmux - ~/.tmux.conf
dotfiles를 어떻게 체계적으로 구성할 수 있을까요? 버전 관리 하에 자체 폴더에 있어야하며, 스크립트를 사용하여 symlinked를 배치해야합니다. 이것은 다음과 같은 이점이 있습니다.
Version Control (Git)
Git 필수 공부 :https://git-scm.com/book/en/v2
Git common error guide : Oh Shit, Git!?!
Third party logs
UNIX 시스템 log 는 /var/log 에 많이 생성되며, 대다수의 linux 는 systemd (system daemon, 많은걸 관리..) 를 사용
Specialized Tools
black box binary 를 디버깅 하는 도구도 있음. 프로그램은 커널이 필요한 작업 수행 할 때 System Calls 를 사용하는데, 그걸 추적함. 리눅스에는 strace 라는 명령어가 그 역할을 함.
network packet 도 확인 가능. tcpdump, Wireshark 는 network packet analyzer 임.
Profiling (일반적으로 profiling 이라 한다면 cpu..)
wall clock time : 컴퓨터가 작업 처리하는데 걸린 시간에 대해, 사람이 인지 할 수 있는 시간
Tool 을 사용하면 Real, User, Sys 구분 가능.
Real : Wall clock elapsed time from start to finish (I/O, netowrk 에 의한 block time 포함)
User : CPU 가 user code 를 실행한 시간
Sys : CPU 가 kernel code 를 실행한 시간
CPU profiler 는 tracing, sampling profiler 가 존재
Tracing profiler : 모든 function call 을 기록
sampling profiler : program 을 주기적으로 probe (ms 단위) 하고, program stack 을 기록
Memory
C, C++ 프로그램 memory leak debugging 을 위해 Valgrind tool 사용 필요
Python 도 memory-profiler 사용하면, 가비지 컬랙팅에 좋음 (?)
Event profiling
perf 는 프로그램과 관련된 시스템 이벤트를 보고 (poor cache locality, 다량의 페이지 오류나 livelock)
Visualization
Flame Graph : 샘플링 프로파일러를 활용한 CPU 프로파일링 정보를 보여주는 가장 일반적인 방법
Call graphs, control flow graphs : 각 함수로, 호출되는 과정을 엣지로 나타내어 프로그램 내부 서브루틴 관계를 표현
Resource monitoring
general monitoring : htop (다양한 단축키 존재), glances
I/O operation : iotop (실시간 I/O 사용량)
Disk Usage : df (partition 마다 보여줌), du (current directory 에서 file 별로 보여줌) -h 붙이면 human readable
Memory usage : free
Open files : lsof (프로세스가 어떤 파일을 여는지..)
Network connections and config : ss (수신 발신의 monitor network packet 통계 모니터링), ip (routing, network device, interface 를 파악)
Network usage : nethogs, iftop (interactive CLI tools for monitoring network usage)
Metaprogramming
building, testing, managing dependency system
make : 가장 흔한 빌드 시스템, 모든 UNIX 컴퓨터에 존재, 간단한 복잡성의 프로젝트에 적합.
make 를 실행하면 Makefile 파일을 참조
make 는 right hand side 를 이용해서 left hand side 를 만들어내는 규칙을 정의
Dependency management
패키지 매니지먼트 Repo : Ubuntu system packages 를 위한 apt, PYPI, RubyGEM, Arch repo
(repo 마다 상호작용 하는 방법이나 세부적인 사항은 각각 매우 다름, 공통적인 용어는 아래와 같음)
versioning (version number) : 프로젝트가 다른 프로젝트의 어떤 버전 또는 버전 범위에 의존하는지 나타내줌
semantic versioning : 버전 숫자가 major.minor.patch 형태를 가짐
new release 가 API 를 바꾸지 않았다면, patch version 을 증가
API 추가가 backwards-compatible way 라면, minor version 을 증가
API 추가가 non-backwards-compatible way 라면, major version 을 증가
depedency management system 을 이용한다면, "lock files" 개념을 접함.
lock file 은 dependency 가 있는 버전을 기입한 파일. 일반적으로 의존성이 있는 프로그램의 new version 업그레이드를 하면 update program 을 실행해 볼 필요가 있음
Continuous integration systems
project 가 커지면 코드를 추가 할 때마다 documentation upload, compiled version upload, run test suite, release to repo, run benchmark 등 해야 할 것이 점점 늘어남. CI 는 "코드가 바뀔때마다 실행되는 것" 의 포괄적인 용어.
CI 에는 Travis CI, Azure Pipelines, GitHub actions 등 많으며, 동작 방식은 거의 다 비슷함
가장 흔한 CI 는 "code 를 push 하면, test suite 를 실행한다 와 같은 규칙임"
event 가 trigger 되면, CI provider 는 virtual machine 을 돌리고, 나의 "recipe" 안의 command 를 실행하고 결과를 저장함.
테스트 스위트(Test suite): 모든 테스트들에 대한 총칭
유닛 테스트(Unit test, 단위 테스트): 특정 기능만 떼어놓고 테스트하는 “마이크로-테스트(micro-test)”
통합 테스트(Integration test): 그 달라진 기능이나 요소들이 함께 제대로 작동하는 지 확인하기 위해 시스템의 더 큰 부분을 실행하는 “매크로-테스트(macro-test)”
회귀 테스트(Regression test): 이전에 버그를 일으켰던 특정 패턴을 구현함으로써 그 버그가 다시 나타나지 않는다는 것을 보장하기 위한 테스트
모킹(Mocking): 관련 없는 기능을 테스팅하는 것을 피하기 위해 가짜 구현(fake implementation)으로 함수, 모듈, 또는 타입을 대체하는 것. 예를 들면, “네트워크를 모킹”하거나 “디스크를 모킹”할 수 있다.
Security and Cryptography
Entropy is a measure of randomness. 엔트로피는 bits 단위로 측정, 엔트로피가 높을수록 강력한 암호화임.
Hash 함수
Hash 함수는 임의 크기의 data 를 fixed size 의 data 로 mapping 해줌. "SHA1" 는 Hast 함수의 예시임.
Hash 함수는 deterministic (같은 입력 값은 항상 같은 결과 도출), Non-invertible,
보통 공식 사이트에서 타사 미러 페이지로 이동하는 다운로드 링크와 함께 파일의 Hash 값을 게시함.
대칭키 암호 (Symmetric cryptography) (ex : AES)
암호화 함수는 출력(암호문)을 제공하며, 키 없이 입력값을 알아내기 어려움.
비대칭키 암호 (Asymmetric cryptography)
public key, private key 사용
SSH
ssh-keygen 실행 시 public_key, private_key 비대칭 키 쌍이 생성 됨.이는 운영체제에서 제공되는 엔트로피를 사용하여 무작위로 생성 됨. 공용키는 그냥 생성되고, 개인키는 암호화되어 저장 됨.
기타 흥미로운 주제들
데몬
데몬 : 항상 백그라운드에서 실행되는 일련의 프로세스, 데몬 프로그램 이름은 항상 d로 끝남. (ex : sshd)
리눅스에서 systemd (시스템 데몬) 은 데몬 프로세스를 실행하고 설정하기 위한 가장 일반적인 솔루션
systemcl 명령어와 상호작용하여 서비스를 활성화, 비활성화, 종료, 재시작 함
systemd 에는 데몬 서비스를 구성하기 위한 쉬운 인터페이스가 존재함
FUSE (Filesystem in User space)
UNIX 에서는 kernel 만이 File system 에 접근 할 수 있음.
그러나 FUSE user program 에 의해서 filesystem 이 접근 되도록 허용 함. FUSE 는 filesystem call 을 위한 user space code 을 run 하도록 해주고, kernel interface 와의 bridge 역할을 해서, Filesystem 에 대한 임의 구현을 가능하게 함.
예를 들어, FUSE 는 virtual filesystem 에서 operation 을 할 때마다 쓰이는데, SSH 를 통해서 remote machine 에 전달하여 원격 시스템의 출력이 다시 사용자에게 반환되도록 함. 이런식으로 로컬 프로그램은 파일이 실제로는 원격 서버에 있지만, 사용자의 컴퓨터에 있는 것처럼 볼 수 있음.
FUSE 예 :
sshfs : SSH 연결을 통해 로컬에서 원격 파일/폴더를 열 수 있음
rclone : Dropbox, Gdrive, Amazon S3, Google Cloud Storage 와 같은 클라우드 서비스를 배치하고 로컬에서 데이터를 씀
gocryptfs : 파일은 암호화되어 저장되지만, 파일 시스템이 마운트되면, 마운트 지점에서 일반 텍스트로 나타냄
kbfs : 처음부터 끝까지 암호화된 분산 파일 시스템
borgbakcup : 검색이 쉽도록 중복 제거, 압축 및 암호화된 백업 실행
API
요즘 대부분의 online 서비스는 API 를 가짐. 대부분의 API 는 structured URL 을 가짐 ("api.service.com" ) . GET 요청을 보내면 대부분 JSON 형식의 Response 가 오는데, jg 같은 도구를 통해 다른 형식으로 변환 가능.
일부 API 는 인증이 필요하며, Request 에 secret token 이 필요함. "QAuth" 라는 프로토콜이 존재 (?)
Tiling Window Manager (키보드로 창 들 배치 가능)
VPN
VPN 을 사용하면, 인터넷을 통해 생성한 트래픽은 실제 위치가 아닌 VPN 제공업체에서 오는 것처럼 보임. VPN 회사가 트래픽 모조리 볼 수도 있음..
QnA
가장 쉽고 좋은 프로파일링 툴은?
가장 쉬운 것 : print time
비교적 발전 된 것 : Valgrind 의 Callgrind, perf, Flamegraph
시스템이 파일을 읽거나, 네트워크 패킷을 보내는 등의 이벤트 (시스템 호출) 을 기다리는 파트가 아마 코드 중 가장 느림. eBPF 는 사용자 프로그램 커널 추적을 도움. 저수준 프로파일링은 bpftrace 도 좋음
2FA 는 뭐고 왜 사용해야 함?
Two Factor Authentication (2FA) 는 계정 보안을 비밀번호 말고 하나 더 추가 보안 단계를 두는 것.계정 주인의 하드웨어에 접근 할 수 있는지 "증명" 해야 함 (ex: 핸드폰 문자) 더 나은 대책으로 YubiKey 와 같은 U2F 솔루션도 있음