다음을 포함 하는 구성 파일이 있습니다 .env
.
DB_PASSWORD={password}
그중에는 /root/.mysql/db00.yml.db
MySQL 루트 계정의 비밀번호가 있습니다. sed
다음을 통해 전달 하려고 합니다 .
cat /root/.mysql/db00.yml.db | sed -i -e "s/DB_PASSWORD=/DB_PASSWORD=(.*)/g" .env
운이 좋지 않아 다음과 같은 몇 가지 변형을 시도했습니다.
sed -i "s/DB_PASSWORD=/DB_PASSWORD=$(cat /root/.mysql/db00.yml.db)" .env
mysqlpwd=$(cat /root/.mysql/db00.yml.db)
# Use the variable in sed -i
sed -i "s/DB_PASSWORD=/DB_PASSWORD=$mysqlpwd/g" .env
이로 인해 오류가 발생합니다.
root@linuxbox:/var/www/www.example.com# mysqlpwd=$(cat /root/.mysql/db00.yml.db)
root@linuxbox:/var/www/www.example.com# sed -i "s/DB_PASSWORD=/DB_PASSWORD=$mysqlpwd/g" .env
sed: -e expression #1, char 33: unknown option to `s'
고쳐 쓰다:
다음을 실행하지 않아도 실패합니다 /g
.
root@linuxbox:/var/www/www.example.com# echo $mysqlpwd
Rjcr/Sn+s/a2QbGx
root@linuxbox:/var/www/www.example.com# cat .env | grep DB_PASSWORD
DB_PASSWORD=(.*)()
root@linuxbox:/var/www/www.example.com# sed -i "s/DB_PASSWORD=/DB_PASSWORD=$mysqlpwd/" .env
sed: -e expression #1, char 33: unknown option to `s'
이 방법 중 어느 것도 작동하지 않는 것 같습니다.
나는 sed 4.7
그것을 실행하고 있습니다 :
root@linuxbox:/var/www/www.example.com# sed --version
sed (GNU sed) 4.7
답변1
본질적으로 비밀번호는 다음을 허용해야 합니다.키보드가 안정적으로 생성할 수 있는 모든 문자. 이는 편집 스크립트 sed
에 삽입될 때 sed
해당 스크립트를 손상시키거나 시스템의 임의 파일에 쓰거나 GNU를 사용하여 임의 명령을 실행할 수 있는 유효한 코드나 문자열이 비밀번호에 쉽게 포함될 수 있음을 의미합니다 sed
(루트로 실행하면 ).
사용자 제공 데이터를 사용해야 하는 경우 sed
데이터를 정리하는 방법을 정확히 알지 않는 한 사용하지 마세요. 나는 개인적으로 쉘이 내가 거의 제어할 수 없는 변수를 확장할 수 있도록 큰따옴표 표현식(작은따옴표 대신)을 sed
요구하는 모든 것을 피하고 싶습니다 .sed
대신 다음을 사용하십시오 awk
.
awk -F '=' '
BEGIN { OFS = FS }
NR == FNR { password = $0; next }
$1 == "DB_PASSWORD" { sub("=.*",""); $2 = password }; 1' /root/.mysql/db00.yml.db .env >.env.new &&
mv .env.new .env
첫 번째 파일의 첫 번째 줄에서 비밀번호를 읽는 것부터 시작합니다(파일에 비밀번호가 그대로 포함된 한 줄만 포함되어 있다고 가정).
그런 다음 파일을 .env
구분된 필드로 구성된 파일로 처리합니다.=
행의 첫 번째 필드가 이면 DB_PASSWORD
행의 첫 번째 필드 =
뒤의 모든 항목을 지우고(이전 비밀번호가 포함된 경우 =
) 비밀번호를 두 번째 필드에 삽입합니다.
수정 여부에 관계없이 모든 행은 로 출력되고 파일은 .env.new
이전 행 .env
으로 대체됩니다 mv
.
결정적으로, 나는 두 파일에서 읽은 데이터를 다음과 같이 사용하지 않습니다.암호내 프로그램에서는 비밀번호의 어떤 부분도 특별하게 취급되는 것을 awk
결코 허용하지 않습니다 . awk
호출 시 대체 문자열로 비밀번호를 사용하면 sub()
문제가 발생할 수 있습니다. 이렇게 하면 &
문자열의 모든 내용이 특수 문자열로 처리되기 때문입니다.
답변2
sed에 다른 구분 기호를 사용해 보십시오... 실제 비밀번호에 따라 여전히 실패할 위험이 있습니다(예:|또는&또는\1).
sed -i "s|DB_PASSWORD=|DB_PASSWORD=$mysqlpwd|" .env
답변3
명령줄 인수에 암호를 입력하면 안 됩니다. 시스템의 모든 사용자가 하나 ps
이상의 top
다른 방법으로 암호를 읽을 수 있습니다. 일부 자동화 시나리오에서는 이것이 가능성이 낮을 수 있다는 것을 알고 있습니다(아무도 상자에 로그인할 가능성이 없기 때문에). 그러나 여전히 나쁜 생각이며, 일부 모니터링 도구나 다른 사람의 일부 스크립트가 로그에 발생할 가능성이 항상 있습니다. 특정 시점에 시스템에서 실행되는 프로세스를 실행하여 어디에 있는지 아는 사람에게 비밀번호를 기록합니다.
을 사용하여 훌륭한 답변을 얻었습니다 . 공유하는 데 사용할 awk
간단한 솔루션도 작성했습니다 . ex
이는 특수 문자가 포함된 모든 비밀번호에 적용됩니다. 유일한 예외는 다음과 같습니다.끝백슬래시로.
파일에 다음이 .env
포함된 경우:
somevar1=someval
somevar2=some other val
DB_PASSWORD=
somevar3=another val
somevar4=val
다음 myscript
을 포함합니다:
/^DB_PASSWORD=$/a
!@#$#% some complicated password "^$%^&@#,.,cmxz\k'dvok][
.
0//j!
x
그냥 실행하면 ex .env < myscript
다음과 같은 결과를 얻을 수 있습니다.
$ ex .env < myscript
$ cat .env
somevar1=someval
somevar2=some other val
DB_PASSWORD=!@#$#% some complicated password "^$%^&@#,.,cmxz\k'dvok][
somevar3=another val
somevar4=val
$
답변4
sed -i -e "
/^DB_PASSWORD=/c\\
DB_PASSWORD=$(sed -e 's:[\\]:&&:g' /root/.mysql/db00.yml.db)
" ./.env
- 변경 명령에 삽입된 값을 보장하기 위해 sed 코드 자체에 비밀번호 삭제 기능을 통합했습니다.
c\