일반적으로 문자열이라는 점에서 작은따옴표와 큰따옴표는 차이가 없습니다.
다만 쉘에서 작은따옴표는 그안의 내용을 번역하지 않고, 큰 따옴표는 번역을 합니다.
echo "$TERM"
결과: xterm
echo ‘$TERM’
결과: $TERM
echo ‘$(date)’
결과: $(date)
echo "$(date)"
결과: 2013. 10. 02. (수) 22:55:06 KST
예를 들어,
sed에서 $라는 끝줄, 혹은 그 줄의 끝을 의미하는데,
쉘에서는 그것을 변수로 취급하고, 그 변수의 값으로 대체합니다.
그러니 그러한 변환이 생기지 않게 작은 따옴표를 사용하는 것입니다.
예를 들어
d=100; echo -e "a\nb\nc" | sed ‘$d’ 라고 입력하게 되면
$는 마지막줄을 의미하고, d는 지우는 명령이라
a
b
이렇게 출력될 것입니다.
d=100; echo -e "a\nb\nc" | sed "$d" 라고 입력하게 되면
$d가 100으로 변환되어, sed "100"이 되어 오류가 발생합니다.
좀 더 상세히 말씀 드리자면,
sed "$d" 라고 입력할 경우,
readline이라는 라이브러리가 입력줄을 사용자 입력으로 부터 읽어냅니다.
이 과정에서 입력하다가 백스페이스 지운다던가, 수정한다던가 하는 작업이 가능합니다. 그게 readline이 하는 역할입니다.
그런데 그 다음 읽어낸 sed "$d"라는 내용의 문자열은 어디서 사용될까요? 그걸 누가 처리할까요?
다름 아닌 쉘이 처리합니다.
쉘은 우분투에서는 기본적으로 dash가 사용되고, bash가 설치된 경우 bash가 사용됩니다.
유닉스에서는 csh이 기본 쉘이죠.
쉘은 조개껍데기라는 뜻인데, 안의 내용물을 감싸고 있다는 의미로,
커널을 감싸고 있습니다.
그 감싸고 있는 외부는 바로 사용자나 프로그램 등입니다.
사용자가 프로그램이 무언가 입력하거나 명령하면 쉘이 그 내용을 받아서 자체적으로 처리를 하던지,
커널에게 처리를 요청합니다.
쉘은 사용자와 커널 사이에서 중간다리 역할을 합니다.
그러니까, sed "$d"라고 입력하면, readline에 의해 그 줄이 읽혀지고,
쉘에게 그 명령이 전달되고, 쉘은 그 명령을 해석합니다.
이 과정에서 bash쉘은 $d라는 것을 변수라고 생각하고, 그 값으로 대체하게 됩니다.
하지만 작은 따옴표를 사용하면, 변환하지 않고, 그대로 프로그램로더에 전달하게 됩니다.
프로그램로더는 프로그램을 실행해주는 놈입니다.
프로그램로더가 명령을 읽어서, sed라는 프로그램을 찾고, 메모리에 로드하고, 실행하면서 그 프로그램에 $d라는 내용을 전달합니다.
그 다음은 sed라는 프로그램에 제어권이 넘어가
sed라는 프로그램이 $d라는 내용을 번역하여 $는 마지막줄이구나, d는 지우는 명령이구나 하는 것입니다.
덧붙이자면…
sed 명령중 치환명령인 s명령을 사용하여 입력된 경로에서 파일명만 출력하는 예제를 작성해본다면,
echo ‘/etc/default/grub’|sed ‘s//([^/]+)$/\1/’ 이렇게 될텐데 지저분하고 읽기 힘들죠?
이럴때를 대비해 s명령에서는 슬래시외에 다른 문자를 사용할 수 있게 허용합니다.
echo ‘/etc/default/grub’|sed ‘s!/([^/]+)$!\1!’ 이런 식으로 말입니다.