자택경비대

2>&-, 2>/dev/null, |&, &>/dev/null and >/dev/null 2>&1 의 차이점에 대해서

stackoverflow

배경지식: 각 fd (file descriptor), 1stdout, 2stderr 그리고 0stdin 을 가리킨다.

N>&-: N에 해당하는 fd를 닫는다.
N>/dev/null: N에 해당하는 fd로 부터의 출력을 /dev/null로 리다이렉팅 한다.
N>&M: N의 출력을 M의 출력과 하나로 합친다.
|&: 2>&1 | 의 축약어이다. (bash4 버전부터 추가)
&>/dev/null: >/dev/null 2>&1 의 축약어이다.

실행 vs 읽기 비트, 리눅스폴더에서는 어떻게 동작하나요?

stackoverflow

사용자가 폴더를 열기 위해서는 실행 비트(+x)가 설정되어 있어야 한다는 것을 깨달았습니다. 왜 실행 권한이 폴더를 읽는데 필요한건가요?


리눅스에서 폴더에 권한을 부여할 때에는, 일반 파일에 권한을 부여할 때와 차이점이 있습니다.

  • 읽기 비트(r)가 유저에게 폴더안의 파일목록을 볼 수 있도록 합니다.
  • 쓰기 비트(w)가 유저에게 파일의 생성, 이름 변경, 삭제, 그리고 폴더의 속성 변경을 가능하게 합니다.
  • 실행 비트(x)가 유저에게 폴더로 들어 올 수 있도록 하고, 내부 파일들에 접근 가능하도록 합니다.
  • Sticky 비트 (실행 비트가 설정되어 있는경우 T 혹은 t)가 폴더 내부의 파일 혹은 폴더의 삭제, 이름 변경이 소유자에 의해 가능하도록 설정합니다.

XY problem이란?

stackoverflow

XY problem이 무엇인가요?

질문을 할때, XY problem에 직면하지 않으려면 어떻게 해야 할까요?


XY problem은 질문을 할 때, 실제적인 문제 그 자체보다는 문제를 해결하려 한 시도에 관해서 질문하는것을 뜻합니다.

예로, 당신이 X라는 문제를 해결하려 Y라는 해결책을 생각해냈을때, 실제로 문제를 해결하는 과정에서 문제를 직면하게 되면 X에 대해서 질문하는것이 아니라 Y에 대해서만 묻는 경우를 말합니다.

이것은 답변을 해주는 사람 입장에서 굉장히 성가신 문제가 될 수 있는데, 왜냐하면 당신이 질문한 내용이 사실은 실제 문제를 해결하는데에 있어 아무런 연관이 없을 가능성이 있기 때문입니다.

bash에서 exec와 eval의 차이는 무엇일까?

stackoverflow

evalexec는 둘다 bash(1)의 내장 명령어 입니다.
exec가 몇 가지 다른 옵션을 가지고 있는것은 알지만 둘의 차이점은 무엇인가요?


evalexec는 완전히 다른 명령어라고 보셔도 됩니다.

$ help exec
exec: exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
    Replace the shell with the given command.

exec cmd가 하는 일은, 그냥 cmd를 실행 했을때와 완전히 동일합니다.
다만, 다른 프로세스를 띄워서 명령어를 실행하는것이 아닌, 현재의 쉘을 명령어로 대체하게 됩니다.
내부적으로는, 예를들어 /bin/ls를 실행 할 경우 fork()를 호출하여서 자식 프로세스를 만든 후에 생성된 자식 프로세스 내에서 exec()를 재호출해서 /bin/ls를 실행하게 됩니다. exec /bin/ls는 이 과정(fork() 호출)을 거치지 않고 명령어를 실행하게 됩니다.

아래의 두 예제를 봅시다.
1.

$ bash -c 'echo $$ ; ls -l /proc/self ; echo foo'
7218
lrwxrwxrwx 1 root root 0 Jun 30 16:49 /proc/self -> 7219
foo

2.

$ bash -c 'echo $$ ; exec ls -l /proc/self ; echo foo'
7217
lrwxrwxrwx 1 root root 0 Jun 30 16:49 /proc/self -> 7217

echo $$ 명령어는 처음에 명령어를 호출한 쉘의 PID값을 출력하게 됩니다. 그리고 /proc/self를 대상으로 ls 명령어로 리스팅을 하게 되면 명령어를 실행하는 프로세스의 PID를 가져올 수 있습니다. 일반적으로, (1)에서 볼 수 있듯이 두 PID는 다른 값을 가지게 되지만, exec를 통해 실행된 명령은 같은 PID를 갖는 것을 알 수 있습니다.
또한, exec명령어가 현재의 쉘을 완전히 대체하였기 때문에, 뒤 따르는 echo foo 명령이 실행되지 않은 것도 확인할 수 있습니다.

한편,

$ help eval
eval: eval [arg ...]
    Execute arguments as a shell command.

eval명령어는 인자를 받아서 현재의 쉘에서 실행하게 됩니다. 쉽게 말하면 eval foo barfoo bar은 완전히 같다 볼 수 있습니다.
다만, 변수들이 명령어가 실행되기 전에 확장되어 변수에 담겨있는 명령어를 실행하는 것이 가능해집니다.

$ unset bar
$ cmd="bar=foo"
$ eval "$cmd"
$ echo "$bar"
foo

try/catch 구문에서 finally의 요점이 뭘까요?

stackoverflow

지난 몇년간 여러 프로그래밍 언어를 사용하면서 try-catch/except-finally 구문을 오래 사용해 왔습니다.
누군가 오늘 저에게 finally의 존재의의에 대해서 질문하였고, 저는 그것에 대해 대답할 수 없었습니다.

질문은 이렇습니다: try-catch 구문 이후에 코드를 작성하면 되는것을 굳이 finally를 사용할 필요가 있을까요?
혹은, 다음 코드에서 어떤 차이점이 있는지 말씀해 주실 수 있을까요?

try{ /* a */ }
catch { /* b */ }
finally { /* c */ }


try{ /* a */ }
catch{ /* b */ }
/* c */

finally 구문은 다음과 같은 3가지 상황 에서 catch 구문으로는 깔끔하게 처리하지 못하는 상황에서 빛을 발합니다:

  • 만약 try 안에 있는 코드에서 return을 할 경우.
  • catch 블록 안에서 잡아낸 예외를 다시 던지는 경우, 혹은 고의 혹은 실수로 새로운 예외를 던질 경우.
  • 만약 catch구문에서 잡아낼 수 없는 예외가 try 블록에서 발생 하였을 때.

물론 finally 구문의 코드를 각각의 return, throw 이전에 붙여넣고 catch 블록을 새로운 try/catch로 감싸서 새로운 예외가 던져질 가능성을 배제할 수 있겠지만, finally 구문을 사용하여 처리하는것이 가장 쉽고 깔끔한 방법입니다.