따옴표 없이 Echo/print bash `ls` 명령 대체

따옴표 없이 Echo/print bash `ls` 명령 대체

다음과 같은 예가 있습니다.

$ a="$(ls)"
$ echo $a
backups cache crash lib local lock log mail opt run snap spool tmp
$
$ echo "$a"
backups
cache
crash
lib
local
lock
log
mail
opt
run
snap
spool
tmp

지금 printf:

$ printf $a
backups
$
$ printf "$a"
backups
cache
crash
lib
local
lock
log
mail
opt
run
snap
spool
tmp

출력이 왜 이렇게 다른가요? 이 상황에서 인용문은 어떤 역할을 합니까? 무슨 일인지 설명해 줄 수 있는 사람이 있나요?

PS 이 동작에 대한 몇 가지 설명을 찾았습니다 ls.
ls의 출력에는 개행 문자가 있지만 한 줄에 나타납니다. 왜?
https://superuser.com/questions/424246/what-is-the-magic-separator- Between-filenames-in-ls-output
http://mywiki.wooledge.org/ParsingLs
다음과 같이 개행 문자를 확인할 수 있습니다.

ls | od -c

답변1

echo $a동일합니까?

echo backups cache crash lib local lock log mail opt run snap spool tmp

그리고 echo "$a"같은

echo 'backups
cache
crash
lib
local
lock
log
mail
opt
run
snap
spool
tmp'

바라보다https://mywiki.wooledge.org/Quotes.

첫 번째 인수 는 그것과 동일한 printf형식 문자열이므로 해당 문자열을 형식으로 사용 하고 형식 문자열에 사용할 항목이 없기 때문에 나머지는 버립니다. 좋다:printf $aprintf backups cache crash lib local lock log mail opt run snap spool tmpbackups%s

$ printf foo whatever
foo$

$ printf '%s\n' foo whatever
foo
whatever

a="$(ls)"파일 이름을 저장하는 스칼라 변수는 깨지기 쉬우므로 생성 하지 말고 대신 a=(*)배열에 저장하세요.

답변2

설명을 주신 @Ed Morton과 @Kusalananda에게 감사드립니다. 내 문제는 파일이 기본적으로 공백이나 탭을 사용하여 분할된다고
항상 생각했다는 것입니다 . ls그러나 실제로는 줄 바꿈으로 구분하지만 터미널에 인쇄할 때 파일을 열 단위(세로 정렬)로 출력하는 것으로 나타났습니다. 개행 문자는 다음을 통해 확인할 수 있습니다.

ls | od -c

@Kusalananda의 답변이 도움이 되므로 댓글 섹션에서 답변으로 이동하겠습니다.

즉, echo해당 인수는 사이에 공백이 포함된 출력입니다. 그것이 바로 그 일입니다 echo.
를 사용하면 echo $a쉘은 $a공백, 탭 및 줄 바꿈을 기반으로 내용을 여러 인수로 분할합니다(그리고 생성된 각 단어에 대해 파일 이름 글로빙도 수행합니다). echo그런 다음 사이에 공백을 두고 인쇄합니다.
를 사용하려면 echo "$a"echo에 하나의 매개변수만 제공하면 됩니다. 문자열에는 "$a"출력의 개행 문자가 포함되어 있으며 ls이는 에 의해 보존되고 출력됩니다 echo.

관련 정보