
저는 셸 스크립트를 디버깅하는 데 사용하고 있으며 문자열을 확인할 수 있도록 양식에서 새 줄 및/또는 캐리지 리턴을 인쇄하는 echo
방법을 알고 싶습니다 . 가능합니까?echo
\n
\r
\n
\r
답변1
ksh93, zsh 또는 bash의 GNU 구현 printf
또는 내장 함수는 printf
문자열에 제어 문자가 포함된 경우 printf %q
ksh93에서 인용된 것처럼 문자열을 출력하는 것과 유사한 작업을 수행합니다.$'...'
입력하다또는개행:
$ string=$'foo\rbar\n' ksh93 -c 'printf "%q\n" "$string"'
$'foo\rbar\n'
$ string=$'foo\rbar\n' zsh -c 'printf "%q\n" "$string"'
foo$'\r'bar$'\n'
$ string=$'foo\rbar\n' bash -c 'printf "%q\n" "$string"'
$'foo\rbar\n'
$ string=$'foo\rbar\n'; /usr/bin/printf "%q\n" "$string"
'foo'$'\r''bar'$'\n'
zsh
셸 에서는 qqqq
매개변수 확장 플래그를 사용하여 이러한 $'...'
따옴표를 무조건 사용할 수도 있습니다.
$ s1=$'\r\n' s2=foobar
$ print -rC1 -- ${(qqqq)s1} ${(qqqq)s2}
$'\r\n'
$'foobar'
답변2
사용량 추적
셸에 따라 추적 디버깅은 인쇄할 수 없는 문자를 명시적인 방식으로 나타낼 수도 있고 나타내지 않을 수도 있습니다.
x=$(printf a\\rb)
(set -x; LC_ALL=C; : "$x")
추적은 이를 지원하는 쉘의 기호를 사용하여 생성됩니다 $'…'
. 예를 들어 ksh, mksh 및 bash는 모두 인쇄됩니다.
+ : $'a\rb'
그러나 dash 및 BusyBox와 같은 다른 셸은 캐리지 리턴을 표준 오류로 인쇄하기 때문에 터미널에 모호한 출력이 발생합니다. 이는 여러분이 피하고 싶은 것입니다. 가능하다면 디버깅하는 동안 bash 또는 (m)ksh(또는 sh 에뮬레이션 모드에서는 zsh)에서 스크립트를 실행하세요.
printf 사용
일부 printf 구현에는 q
지정자가 있습니다. %q
와 유사 %s
하지만 출력을 셸로 다시 구문 분석할 수 있도록 일부 문자를 인용합니다. 결과도 시각적으로 명확합니다. 예를 들어 탭이 로 인쇄됩니다 \t
. GNU printf 구현은 %q
.
LC_ALL=C printf %q\\n "$x"
Linux의 dash에서는 외부 printf 유틸리티를 사용해야 합니다 /usr/bin/printf
. BusyBox에서는 이 기능을 사용할 수 없습니다.
고양이 파이프를 통해
많은 구현에서는 공백 대신 cat
탭과 같은 인쇄되지 않는 문자를 시각적으로 출력할 수 있습니다 . ^I
이는 분명하지 않습니다. 탭은 두 문자와 구별할 수 없습니다 ^I
.
printf '%s\n' "$x" | cat -vet
16진수 덤프
16진수 덤프를 사용하여 출력을 인쇄할 수 있습니다. 이를 수행하는 이식 가능한 방법은 od
.
$ x=$(printf a\\tc\\rb); printf %s "$x" | od -tx1'
0000000 61 09 63 0d 62
0000005
BSD 유틸리티hexdump
( hd
약어)는 *BSD 및 Debian 기반 Linux 배포판에서 사용할 수 있으며 인쇄 가능한 문자도 출력하므로 더 좋습니다.
$ x=$(printf a\\tc\\rb); printf %s "$x" | hd
00000000 61 09 63 0d 62 |a.c.b|
00000005
인기 유틸리티xxd
(Vim과 함께 배포되지만 대부분의 배포판에서 별도 패키지로 사용 가능) 출력 형식은 비슷합니다.
$ x=$(printf a\\tc\\rb); printf %s "$x" | xxd -g1
00000000: 61 09 63 0d 62 a.c.b
힘든 길
sed를 사용하면 인쇄할 수 없는 모든 문자를 하나씩 번역할 수 있습니다. 이식 가능한 스크립트를 만들려면 인쇄 가능한 문자를 실제로 sed에 전달해야 합니다. 쉘 스크립트에서 sed를 호출하면 이를 사용하여 printf
sed 스크립트를 구성할 수 있습니다. 다음 스크립트는 가장 일반적인 제어 문자를 백슬래시 이스케이프로 인쇄합니다. 필요한 경우 더 추가합니다.
#!/bin/sh
export LC_ALL=C
sed_script=$(printf '
s/\\\\/\\\\\\\\/g
s/'\''/\\\\'\''/g
s/\a/\\\\a/g
s/\b/\\\\b/g
s/\t/\\\\t/g
s/\f/\\\\f/g
s/\r/\\\\r/g
s/\033/\\\\e/g
$!s/$/\\\\n/
')
quoted=$(printf %sa "$2" | sed "$sed_script" | tr -d '\n')
printf "%s=\$'%s'\n" "$1" "${quoted%a}"
용법:quoted-dump x "$x"