programing

bash에서 "cat << EOF"는 어떻게 작동합니까?

linuxpc 2023. 5. 6. 14:07
반응형

bash에서 "cat << EOF"는 어떻게 작동합니까?

줄을 입력하기 (프로램에여줄러입입했작습다니성야해를트립스크위해기그하력력을(▁i했▁to다습니▁a▁script▁needed▁(프▁to▁write▁to-▁multi▁enter작야▁input).psql).

약간의 구글 검색 후, 다음 구문이 작동한다는 것을 발견했습니다.

cat << EOF | psql ---params
BEGIN;

`pg_dump ----something`

update table .... statement ...;

END;
EOF

다중 줄 이게렇하다줄올생이다니성게됩바르문열자중면▁(from다▁this▁constructs▁multi니-)이 올바르게 구성됩니다.BEGIN;END;을 에포함대입파합링니다이프로으한력▁inclusive다니합에.psql.

하지만 저는 그것이 어떻게/왜 작동하는지 모르겠습니다, 누군가 설명해 주시겠습니까?

제가 주로 언급하는 것은cat << EOF,알고있어요>, 파일출력,>>파에추니다됩가에 됩니다.<파일에서 입력을 읽습니다.

가 입니까?<<정확히 그렇습니까?

그리고 그것을 위한 man 페이지가 있습니까?

cat <<EOF구문은 셸 변수, 파일 또는 파이프에 다중 줄 문자열을 할당할 때와 같이 Bash에서 다중 줄 텍스트로 작업할 때 매우 유용합니다.

『 』의 예cat <<EOFBash의 구문 사용:

셸 변수에 다중 줄 문자열 할당

$ sql=$(cat <<EOF
SELECT foo, bar FROM db
WHERE foo='baz'
EOF
)

$sql변수에 줄 바꿈 문자도 포함됩니다.를 사용하여 확인할 수 있습니다.echo -e "$sql".

다중 줄 문자열을 Bash의 파일로 전달

$ cat <<EOF > print.sh
#!/bin/bash
echo \$PWD
echo $PWD
EOF

print.sh이제 파일에 포함된 내용:

#!/bin/bash
echo $PWD
echo /home/user

Bash의 파이프에 다중 줄 문자열 전달

$ cat <<EOF | grep 'b' | tee b.txt
foo
bar
baz
EOF

b.txt에 파에포됨이 되어 있습니다.bar그리고.baz이 인라로 됩니다. 동일한 출력이 출력됩니다.stdout.

stdin에 문자열을 제공하는 것을 hereoc 형식이라고 합니다.자세한 내용은 https://en.wikipedia.org/wiki/Here_document#Unix_shells 을 참조하십시오.


man bash:

여기 문서

이 리디렉션 유형은 셸에 현재 소스의 입력을 읽도록 지시합니다. 이 경우 뒤에 공백이 없는 단어만 포함된 줄이 표시됩니다.

이때까지 읽은 모든 행이 명령의 표준 입력으로 사용됩니다.

여기 문서의 형식은 다음과 같습니다.

          <<[-]word
                  here-document
          delimiter

단어에 대한 매개 변수 확장, 명령 대체, 산술 확장 또는 경로 이름 확장이 수행되지 않습니다.단어에 따옴표가 있는 문자가 있는 경우 구분 기호는 단어에서 따옴표를 제거한 결과이며 여기 문서의 줄은 확장되지 않습니다.단어를 따옴표로 묶지 않은 경우 여기에 있는 문서의 모든 행은 매개 변수 확장, 명령 대체 및 산술 확장의 대상이 됩니다.후자의 경우, 문자 시퀀스는\<newline> 무됩니다입니다.\문자를 따옴표로 묶는 데 사용해야 합니다.\,$,그리고.`.

가 리렉션연가인 <<-그러면 모든 선행 탭 문자가 입력 줄과 구분 기호가 포함된 줄에서 제거됩니다.이를 통해 셸 스크립트 내의 여기 문서를 자연스러운 방식으로 들여쓸 수 있습니다.

이 경우 "EOF"는 "Here Tag"로 알려져 있습니다.으로 기적으로.<<Here에서는 ""tag" "tag" "tag" "tag" "tag" "tag" "continue" "continue" ""까지 입력할 .Here할 수 , 이태의이원대지수있로다습니정할하는름은그▁as▁you▁often다s있▁tag니습수▁this'▁it지할이정입니다. 자주EOF또는STOP.

여기 태그에 대한 몇 가지 규칙:

  1. 태그는 대문자 또는 소문자 문자열이 될 수 있지만 대부분의 사용자는 일반적으로 대문자를 사용합니다.
  2. 해당 줄에 다른 단어가 있는 경우 태그는 여기 태그로 간주되지 않습니다.이 경우 문자열의 일부로 간주됩니다.태그는 태그로 간주하기 위해 별도의 줄에 있어야 합니다.
  3. 태그는 해당 줄에 태그로 간주되는 선행 또는 후행 공백이 없어야 합니다.그렇지 않으면 문자열의 일부로 간주됩니다.

예:

$ cat >> test <<HERE
> Hello world HERE <-- Not by itself on a separate line -> not considered end of string
> This is a test
>  HERE <-- Leading space, so not considered end of string
> and a new line
> HERE <-- Now we have the end of the string

POSIX 7

인용 니티엠적견케적.man bash하지만 대부분은 POSIX 7입니다. http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_07_04 :

리디렉션 연산자 "<<" 및 "<-" 모두 "여기 문서"로 알려진 셸 입력 파일에 포함된 행을 명령 입력으로 리디렉션할 수 있습니다.

여기에 있는 문서는 다음 이후에 시작하는 단일 단어로 처리되어야 합니다.<newline> 구분 와 " " " " " " " " " " " " 을 포함하는 이 있을 됩니다.<newline><blank> 시작합니다그런 다음 문서가 있으면 다음 문서가 시작됩니다.형식은 다음과 같습니다.

[n]<<word
    here-document
delimiter

여기서 n은 파일 설명자 번호를 나타냅니다.숫자가 생략된 경우 여기에 있는 문서는 표준 입력(파일 설명자 0)을 참조합니다.

단어에 어떤 문자가 인용될 경우, 구분 기호는 단어에 대한 인용 제거를 수행하여 형성되어야 하며, 여기에 있는 문서 행은 확장되지 않습니다.그렇지 않은 경우 구분 기호는 단어 자체여야 합니다.

단어의 문자를 따옴표로 묶지 않은 경우 매개 변수 확장, 명령 대체 및 산술 확장을 위해 여기 문서의 모든 행을 확장해야 합니다.에, 우경이는,<backslash>입력에서 동작은 다음과 같이 동작합니다.<backslash>이중 따옴표 내부(이중 따옴표 참조).그러나 이중 따옴표(')는 "$(")" 또는 "${}" 내에 이중 따옴표가 나타나는 경우를 제외하고는 여기 문서 내에서 특별히 취급되지 않습니다.

이면 모든 리렉션기가 "<-", " " "<tab>입력 라인과 후행 구분 기호를 포함하는 라인에서 문자를 제거해야 합니다.한 줄에 둘 이상의 "<<" 또는 "<" 연산자가 지정된 경우, 첫 번째 연산자와 관련된 여기 문서는 애플리케이션에 의해 먼저 제공되어야 하며 셸에 의해 먼저 읽혀져야 합니다.

터미널 장치에서 여기에 있는 문서를 읽고 셸이 상호 작용하는 경우, 구분 기호가 인식될 때까지 각 입력 라인을 읽기 전에 셸 변수에 설명된 대로 처리된 변수 PS2의 내용을 표준 오류에 기록해야 합니다.

몇 가지 예는 아직 제시되지 않았습니다.

따옴표는 매개 변수 확장을 방지합니다.

따옴표 없이:

a=0
cat <<EOF
$a
EOF

출력:

0

인용문 포함:

a=0
cat <<'EOF'
$a
EOF

또는 (유효하지만 유효함):

a=0
cat <<E"O"F
$a
EOF

출력:

$a

하이픈으로 선행 탭 제거

하이픈 사용 안 함:

cat <<EOF
<tab>a
EOF

<tab>문자 그대로의 탭이며 를 사용하여 삽입할 수 있습니다.Ctrl + V <tab>

출력:

<tab>a

하이픈 사용:

cat <<-EOF
<tab>a
<tab>EOF

출력:

a

이것은 물론 존재하기 때문에 당신이 당신의 것을 들여놓을 수 있습니다.cat읽기 쉽고 유지 관리가 용이한 주변 코드처럼.예:

if true; then
    cat <<-EOF
    a
    EOF
fi

. preferred 안타공문는자적용지않. POSIXtab여기에 들여쓰기. 그렇습니다.

고양이 대신 티를 사용하는 것.

원래 질문에 대한 답은 아니지만, 어쨌든 저는 이것을 공유하고 싶었습니다.루트 권한이 필요한 디렉토리에 구성 파일을 만들어야 했습니다.

이 경우 다음은 작동하지 않습니다.

$ sudo cat <<EOF >/etc/somedir/foo.conf
# my config file
foo=bar
EOF

리디렉션이 sudo 컨텍스트 외부에서 처리되기 때문입니다.

대신 이것을 사용하게 되었습니다.

$ sudo tee <<EOF /etc/somedir/foo.conf >/dev/null
# my config file
foo=bar
EOF

<< EoF기본적으로 다음을 의미합니다.

<<의 파일에합니다." "" 음 줄 부 다 시 입 줄 력 파 코 것 처 일 에 있 럼 처 리 는 드 가 별 의 도 읽 "

EoF"단어 직후에 읽는 것을 중단합니다."EoF입력 " 중행 입에서찾수을있다니습다력."다"에서 찾을 수 .

다른 답변에서 설명한 것처럼 다중 줄 입력을 여기 문서라고 합니다.

여기 문서는 종종 후속 프로세스로 전달될 출력을 생성하는 데 사용됩니다.를 들어 를들면입니다.cat << EoF여기 문서를 사용하여 원하는 출력을 생성할 수 있습니다.

다음은 여기 문서를 사용하여 텍스트 문서를 즉시 작성하는 예입니다.

cat << EoF > ./my-document.txt
Hello world
Have a nice day
EoF

위의 답변에 대한 약간의 확장입니다.에 오는 행>입력을 파일로 유도하여 기존 내용을 덮어씁니다.그러나 특히 편리한 사용법은 이중 화살표입니다.>>다음과 같이 새 콘텐츠를 파일 끝에 추가합니다.

cat <<EOF >> /etc/fstab
data_server:/var/sharedServer/authority/cert /var/sharedFolder/sometin/authority/cert nfs
data_server:/var/sharedServer/cert   /var/sharedFolder/sometin/vsdc/cert nfs
EOF

이렇게 하면 사용자의 작업 범위가 확장됩니다.fstab실수로 내용을 수정할 걱정을 하지 않아도 됩니다.

cat << \EOT (백슬래시 참조)는 내부 변수를 확장하지 않으며 cat << EOT는 확장할 수 있습니다.

예:

FOO="bar"

cat << \EOT > foobar.txt
echo "$FOO"
EOT

will output: 에코 $FOO

반면:

FOO="bar"

cat << EOT > foobar.txt
echo "$FOO"
EOT

will 출력: 에코 "bar

json 파일을 만드는 예:

cat << EoF > ./allaccess.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:*"
      ],
      "Resource": [
        "arn:aws:s3:::*"
      ]
    }
  ]
}
EoF

그 결과:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:*"
      ],
      "Resource": [
        "arn:aws:s3:::*"
      ]
    }
  ]
}

단히말해서간,서해말,EOF마커(그러나 다른 리터럴도 사용할 수 있음)는 입력을 여러 줄로 제공할 수 있는 세레독 형식입니다. 많은혼어발생합떻게까니은란?▁how까니▁comes▁from▁a?cat실제로 효과가 있는 것 같습니다.사용할 수 있습니다.cat와 함께>>또는>다음과 같이:

$ cat >> temp.txt
line 1
line 2

하는 동안에cat콘솔에 수동으로 쓸 때 이런 방식으로 사용할 수 있습니다. 입력을 도구에서 재사용하고 들여쓰기, 공백 등을 유지할 수 있도록 보다 명확한 방식으로 제공하려면 편리하지 않습니다.
은 Heredoc과 함께 작업하지 할 수 .stdin다른 텍스트 편집기에 입력합니다.위키백과 기사의 의미는 다음과 같습니다.

소스 코드 파일의 섹션으로, 별도의 파일인 것처럼 처리됩니다.

이것은 반드시 원래 질문에 대한 대답이 아니라, 제가 직접 테스트한 결과를 공유하는 것입니다.다음 항목:

<<test > print.sh
#!/bin/bash
echo \$PWD
echo $PWD
test

다음과 동일한 파일을 생성합니다.

cat <<test > print.sh
#!/bin/bash
echo \$PWD
echo $PWD
test

그래서, 저는 cat 명령어를 사용하는 것이 무슨 의미가 있는지 모르겠습니다.

여기 문서는 bash 루프에서도 작동한다는 것에 주목할 필요가 있습니다.다음 예제에서는 테이블의 열 목록을 가져오는 방법을 보여 줍니다.

export postgres_db_name='my_db'
export table_name='my_table_name'

# start copy 
while read -r c; do test -z "$c" || echo $table_name.$c , ; done < <(cat << EOF | psql -t -q -d $postgres_db_name -v table_name="${table_name:-}"
SELECT column_name
FROM information_schema.columns
WHERE 1=1
AND table_schema = 'public'
AND table_name   =:'table_name'  ;
EOF
)
# stop copy , now paste straight into the bash shell ...

output: 
my_table_name.guid ,
my_table_name.id ,
my_table_name.level ,
my_table_name.seq ,

아니면 새로운 라인이 없어도.

while read -r c; do test -z "$c" || echo $table_name.$c , | perl -ne 
's/\n//gm;print' ; done < <(cat << EOF | psql -t -q -d $postgres_db_name -v table_name="${table_name:-}"
 SELECT column_name
 FROM information_schema.columns
 WHERE 1=1
 AND table_schema = 'public'
 AND table_name   =:'table_name'  ;
 EOF
 )

 # output: daily_issues.guid ,daily_issues.id ,daily_issues.level ,daily_issues.seq ,daily_issues.prio ,daily_issues.weight ,daily_issues.status ,daily_issues.category ,daily_issues.name ,daily_issues.description ,daily_issues.type ,daily_issues.owner

언급URL : https://stackoverflow.com/questions/2500436/how-does-cat-eof-work-in-bash

반응형