이것이 명확하게 보여주듯이 저는 프로그래밍(/스크립팅?)이 처음입니다.
목적:
새 Linux 인스턴스를 자동으로 설치/구성하기 위해 재사용 가능한 스크립트를 만들려고 합니다. 계속해서 문제가 발생하기 때문입니다. 이 경우에는 /etc/pam.d/sshd를 조작하고 있습니다.
학습... sed는 저에게 인용문, 휴식 시간 및 모든 기본 사항에 대해 정말 가르쳐주었습니다.
보시다시피, 제대로 작동했지만 몇 가지 문제가 있습니다. (이 접근 방식이 얼마나 부서지기 쉬운지 지적할 사람이 있을지 모르겠습니다.)
질문 1-2)
변수 파일- seinsert.sh에 인수로 전달됨
sedfind="# Standard Un\*x authentication."
#sedfind=".* Standard Un\*x authentication"
sedinsert="I am a \nmulti line variable \nand I kind of work"
sedfile=sshd
예를 들어 sed 명령에 필요한 모든 문자를 이스케이프 처리하거나 여기서 와일드카드를 사용하겠습니다. 왜냐하면 업데이트할 때 변수 파일을 한 번만 변경하면 되기 때문입니다. 적어도 저에게는 이것이 A입니다. 더 깨끗한 것.
또한 변경 사항이 출력/결과에 어떤 영향을 미치는지 쉽게 확인할 수 있으므로 이해하는 데 큰 도움이 됩니다.
Q1. 여기에 인용한 내용과 새 줄이 맞나요? 이 방법이 효과가 있는 것 같은데 다른 방법이 있나요? 이 상황을 깨뜨릴 캐릭터를 곧 만나게 될 것 같은 기분이 듭니다. 예가 있나요?
Q2. 필요한 경우 파일을 더 쉽게 사용할 수 있도록 변수를 여러 줄로 분할할 수 있습니까(예: 줄 끝에 \를 사용하는 등) - source 및 sed가 곧 제공될 것임을 기억하세요.
어쩌면 스크립트의 다른 명령이 이를 처리할 수 있을까요? (Grep? 아니면 다른 sed?.
질문 2
seinsert.sh
set -x
source $1
sed -i "\|$sedfind|a\ \n$sedinsert" $sedfile
가능한 한 깔끔하게 유지하고 변수 주위에 따옴표를 사용하지 않으려고 노력하고 있습니다. 현재 교체할 다른 것이 있지만 다음에는 명령을 변수로 전달하는 것을 고려할 수 있습니다.
나는 이 아이디어에 전적으로 동의하지는 않지만 그 이유가 이해가 되기를 바랍니다... 즉, @#" 등과 같이 "어려운" 문자가 포함된 다양한 파일을 변경하는 데 사용됩니다.
Q: 그래서 명령 자체에 첫 번째 새 줄을 넣어야 합니다(|a\/N....). 원하지 않거나 여러 개의 빈 줄을 포함하고 싶다면 변수 자체에 넣을 수 있는 방법이 있습니까?
질문 3
sed에서는 패턴 구분 기호(올바른 용어?)를 \에서 |로 설정할 수 있습니다. 내가 여기 있는 것처럼.
하지만 작동하는 파일을 찾았다고 생각할 때마다 내가 보는 다음 파일에 해당 파일이 포함되어 있음을 확신합니다.
Q: 다른 곳에서는 거의 사용되지 않는 제안/표준 퍼지 구분 기호가 있습니까? 그래서 #| 대신 일부 러시아어 문자(러시아인에게는 사과드립니다)와 같이 파일에서 항상 찾을 수 없습니다.
왜 모두가 common을 사용하는지 조금 혼란스럽습니다. 이로 인해 사람들이 다른 답변(예: / 파일 경로)에서 온갖 종류의 혼란을 겪는 것 같습니다.
질문 4: 이제 이 모든 것을 어떻게 해야 합니까?
pam.sshd의 몇 줄을 예로 들어 보겠습니다.
# PAM configuration for the Secure Shell service
# Standard Un*x authentication.
@include common-auth
# Disallow non-root logins when /etc/nologin exists.
account required pam_nologin.so
너무 길어서 죄송합니다. 전체 과정을 설명할 가치가 있다고 생각했습니다.
답변1
~부터seinsert.shsource
bash를 사용하고 있다고 가정하는 명령이 포함되어 있습니다 .
질문 1-2)
Q1.
당신 말이 맞아요.
Q2.
실제로, 개행 문자가 있는 변수를 갖는 것이 가능합니다:
sedinsert="I am a
multi line variable
and I kind of work"
그냥 구매하세요변수 파일유효한 bash 스크립트입니다.
귀하의 목적에 따라 다음 변수를 사용할 수 있습니다(각 개행 문자 앞에 백슬래시 추가).
sedinsert="I am a \
multi line variable \
and I kind of work"
sed와 함께 사용할 때는 백슬래시가 필요합니다. 이제 변경 없이 명령을 사용할 수 있습니다.
sed -i "\|$sedfind|a\ \n$sedinsert" $sedfile
질문 2
sed 명령은 a \
다음과 같이 개행 문자와 함께 사용해야 합니다.
sed -i "\|$sedfind|a \
$sedinsert" $sedfile
예를 들어 다음 명령은
sed "/ping/a \
pong" -i file.txt
pong
하위 문자열 "ping"을 포함하는 각 문자열 뒤에 문자열이 추가됩니다(추가 줄 바꿈 및 공백 없음).
모양이 마음에 들지 않으면 $'word'
메커니즘을 사용하여 줄 바꿈을 나타낼 수 있습니다.
sed "/ping/a \"$'\n'"pong" -i file.txt
또는
newline=$'\n'
sed "/ping/a \${newline}pong" -i file.txt
질문 3
먼저, 각 기호는무늬(예 sedfind
: )에는 포함되어 있지 않습니다. 파일의 내용은 $sedfile
중요하지 않습니다. 구분 기호는 패턴의 끝을 나타내는 데에만 사용됩니다. 둘째, 패턴에 구분 기호를 사용해야 하는 경우 백슬래시를 사용하여 모든 항목을 이스케이프 처리할 수 있습니다.
sed "\|bar\|bar| a \
foo-foo"
foo-foo
포함된 각 문자열 뒤에 문자열을 추가합니다 .bar|bar
사용 가능하지만 다른 곳에서는 거의 사용되지 않는 권장/표준 퍼지 구분 기호가 있습니까?
나는 그것에 대해 아무것도 모른다.
그런데 내 버전의 sed는 러시아어 문자를 구분 기호로 허용하지 않습니다(오류 메시지 delimiter character is not a single-byte character
).
일반화하다
이제 이것을 사용할 수 있습니다변수 파일:
sedfind="# Standard Un\*x authentication." # all occurrences of symbol '|' must be escaped by backslash as far as '|' is sed pattern delimiter
#sedfind=".* Standard Un\*x authentication"
sedinsert="I am a \
multi line variable \
and I kind of work"
sedfile=sshd
이seinsert.sh:
set -x
source $1
sed -i "\|$sedfind|a \
$sedinsert" $sedfile
변수를 큰따옴표로 묶는 것이 더 좋습니다(그렇지 않으면 특수 기호가 있는 파일 이름에서 스크립트가 중단됩니다).
set -x
source "$1"
sed -i "\|$sedfind|a \
$sedinsert" "$sedfile"
이 스크립트는 패턴과 일치하는 파일의 각 줄 뒤에 문자열을 추가합니다 $sedinsert
.$sedfile
$sedfind
사람들이 유용하다고 생각할 수 있는 인용, 정규식 및 sed 스크립트에 대한 좋은 튜토리얼:http://www.grymoire.com/Unix/