makefile에서 cygwin 경로를 Windows 경로로 변경하고 싶습니다. 이를 위해 나는 사용하고 있습니다
CURDIR := `pwd`
WINDIR := $(shell echo $(CURDIR) | sed -e "s/\/cygdrive\/\(.\)/\1:/" | sed -e 's/\//\\/g')
gnumake를 사용하여 이 makefile을 실행하면 다음 오류가 발생합니다.
sed.exe: -e expression #1, char 8: Unterminated `s' command
그러나 cygwin 쉘에서 직접 다음 명령을 실행하면 원하는 출력을 얻습니다.
$: pwd | sed -e "s/\/cygdrive\/\(.\)/\1:/" | sed -e 's/\//\\/g'
위 명령은 셸에서 아무런 불만 없이 잘 실행됩니다. 이 문제가 발생한 이유는 무엇이며 가능한 해결 방법은 무엇입니까?
답변1
보고 있는 문제를 설명하기 위해 두 번째 sed
명령을 사용하면 문제가 발생합니다.
sed -e 's/\//\\/g'
make
\
이스케이프에 사용할 수 있는 특수 문자 %
및 (단일 백슬래시) \\
로 변환할 수 있는 이스케이프 시퀀스 역할을 합니다.\
%
백슬래시는 두 개 이상의 연속적인 백슬래시가 뒤따르는 경우를 제외하고 그대로 보존되므로 문제를 일으키지 않고 \/
유지됩니다 (이것이 문제를 일으키는 유일한 장소인 이유입니다).\/
따라서 sed
실행되는 실제 명령은 다음과 같습니다.
sed -e 's/\//\/g'
예를 들어, 다른 구분 기호를 사용하면 명령이 어떻게 불완전한지 확인하는 것이 더 쉽습니다 #
.
sed -e 's#/#/g'
첫째, #
닫는 구분 기호(이 경우)가 누락되었습니다. 게다가 대체 결과는 예상된 a /
대신 a가 됩니다.\
추가 백슬래시를 추가하여 문제를 해결할 수 있습니다(또는 두 개도 가능).
sed -e 's/\//\\\/g'
하지만 이 코드를 읽는 사람에게는 이것이 이상하게 보일 수 있으므로 무슨 일이 일어나고 있는지 설명하기 위해 주석을 추가하는 것이 좋습니다.
또 다른 좋은 아이디어는 두 배로 늘리는 것입니다.모든make
백슬래시를 사용하여 레이어 중 하나를 이스케이프 시퀀스로 명시적 으로 사용합니다.
sed -e 's/\\//\\\\/g'
아, 여전히 안 좋네요... Except 이외의 구분 기호를 사용하면 #
도움이 될 수 있지만 아마도 그다지 많지는 않을 것입니다.
sed -e 's#/#\\\\#g'
여기에서 사용하는 특정 사례 sed
, 즉 Cygwin 경로를 Windows 경로로 변환하는 경우 실제로 사용할 수 있습니다.cygpath --windows
, @HaiVu가 댓글에서 지적했듯이.