BASH 및 캐리지 리턴 동작


11

한 가지 간단한 질문이 있습니다.
bash (4.4.11을 사용하고 있음)가 일반으로 구분 / 끝나는 줄 / 텍스트를 표시하지 않는 것이 정상 \r입니까?

이 동작을보고 약간 놀랐습니다.

$ a=$(printf "hello\ragain\rgeorge\r\n")
$ echo "$a"
george

그러나 "안녕 다시"텍스트는 여전히 "숨겨져"있습니다.

$ echo "$a" |od -w32 -t x1c
0000000  68  65  6c  6c  6f  0d  61  67  61  69  6e  0d  67  65  6f  72  67  65  0d  0a
          h   e   l   l   o  \r   a   g   a   i   n  \r   g   e   o   r   g   e  \r  \n

그리고 우리가 bash를 가지고 노는 즉시 괜찮습니다. 그러나 이것이 잠재적 인 보안 위험입니까? 변수 "a"의 내용이 외부에서 나오고 단순히 hello 대신 "bad command"를 포함하면 어떻게됩니까?

이번에는 조금 안전하지 않은 또 다른 테스트 :

$ a=$(printf "ls;\rGeorge\n")
$ echo "$a"
George
$ eval "$a"
0                   awkprof.out       event-tester.log  helloworld.c      oneshot.sh         rightclick-tester.py  tmp                    uinput-simple.py
<directory listing appears with an error message at the end for command George>

숨겨진 rm대신 숨겨진 것을 상상해보십시오 ls.

echo -e를 사용할 때와 동일한 동작 :

$ a=$(echo -e "ls;\rGeorge\r\n"); echo "$a"
George

내가 잘못한 것이 나인가?

답변:


20

귀하의 echo "$a"인쇄는 "안녕하세요", 다시 (무엇 라인의 시작 부분으로 이동 \r, 다시 돌아 간다 "다시" "조지을"인쇄물을 인쇄하지) 다시 가고, 다음 행으로 이동 ( \n). 그것은 모두 완벽 정상이지만, 같은 chepner의 : 점 밖으로, 그것은 강타와 함께 할 아무것도하지 않습니다 \r\n(당신이 전체 출력을 얻을 이유입니다 때 파이프 명령을하지 배쉬으로, 단말기에 의해 해석됩니다 od).

당신은 이것을 더 잘 볼 수 있습니다

$ a=$(printf "hellooooo\r  again,\rgeorge\r\n")
$ echo "$a"

덮어 쓴 텍스트의 끝이 남길 것입니다.

georgen,o

(당신은 충분히 문자로 덮어 확신 할 수있는 경우에만 등), 그들의 출력, 사용하지 않는하지만 당신은 정말 숨기기 명령에 그것을 사용할 수 없습니다 eval당신이 보여로 (하지만 사용하여 eval일반적으로 권장되지 않음). 더 위험한 속임수는 CSS를 사용하여 웹 사이트에서 복사하여 붙여 넣을 명령을 숨기는 것입니다.


고마워요 테스트에서 마지막 두 단어를 완전히 덮어 쓸 수있는 마지막 단어를 사용하는 것이 운이 좋았습니다.
George Vasiliou

2
그러나 이것은 실제로는 아무 관련이 없습니다 bash. 캐리지 리턴을 "표시"하는 방법 또는 덮어 쓴 문자를 표시하는 방법 은 전적으로 터미널에 달려 있습니다. 예를 들어, 터미널 -\r|이 파이프가 아니라 더하기 부호와 유사한 것으로 표시 되는 것이 완벽하게 유효합니다 .
chepner

@chepner 알아두면 좋습니다! 공유해 주셔서 감사합니다. 나는 이것이 단지 bash 행동이라고 생각했다.
George Vasiliou

@GeorgeVasiliou Nope, bash그냥 파일에 바이트를 쓴다. 바이트를 읽어 해석하는 사람 누구에게나 달려 있습니다.
chepner

Nitpick : printf(또한 독립 실행 파일로서 존재하지만), 해석하는 기본 명령 떠들썩한 인 \r2 바이트 (a 서열 0x5c0x72캐리지 리턴 (단일 바이트를 생성한다 : 0x0d.) 다음에, 긍정 터미널 바이트 0x0d를 특별한 방식으로 해석하지만 원래 문자열을 해석하지는 않습니다 \r.
Suzanne Dupéron

6

유닉스 세계에서 캐리지 리턴 (일반적으로 \r프로그래밍 언어에서 와 같이 인코딩 됨 )은 주목할만한 제어 문자입니다. 줄 바꿈 ( 줄 바꿈 이라고도 함 ) 이외의 다른 문자와 같이 텍스트 줄 안에 캐리지 리턴을 줄 수 있습니다 .

특히 bash 스크립트에서 캐리지 리턴은 문자 및 숫자와 같은 일반적인 단어 구성 문자입니다. 캐리지 리턴의 특수 효과는 쉘이 아닌 터미널에서 발생합니다.

캐리지 리턴은 제어 문자 입니다. glyph 를 표시하는 대신 터미널에 인쇄 하면 터미널이 특수 효과를 수행합니다. 캐리지 리턴의 경우 특수 효과는 커서를 현재 줄의 시작 부분으로 이동하는 것입니다. 따라서 가운데에 캐리지 리턴이 포함 된 행을 인쇄하면 후반이 전반에 기록됩니다.

다른 여러 제어 문자에는 특수 효과가 있습니다. 백 스페이스 문자는 커서를 한 위치 왼쪽으로 이동합니다. 벨 문자는 단말기가 소리를 내거나 사용자의주의를 끌도록합니다. 이스케이프 문자 는 모든 종류의 특수 효과를 가질 수 있는 이스케이프 시퀀스 를 시작합니다 .

신뢰할 수없는 출력을 표시하면 제어 문자를 제거하거나 이스케이프해야합니다. 캐리지 리턴뿐만 아니라 여러 가지, 특히 이스케이프 문자가 발생하여 모든 종류의 나쁜 영향을 줄 수 있습니다. 파일“cating”이 잠재적 인 보안 위험이 될 수 있습니까?를 참조하십시오 . 그리고 어떻게 터미널에서 이스케이프 시퀀스 공격을 피하기 위해? 주제에 대한 자세한 내용.


0

형식이 있는 printf함수를 사용하여 bash 변수에서 캐리지 리턴을 볼 수 있습니다 %q.

$ TESTVAR="$(printf ' Version: 1 \r Build: 20180712 \r Test: 1324')"

$ printf %q $TESTVAR
Version:1$'\r'Build:20180712$'\r'Test:1324

출처와 추가 자료 :

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.