3가지 작업을 수행하는 make 스크립트가 있습니다.
- MySQL 데이터베이스 가져오기
- 모바일 프로필
- 구성 파일 구성
이러한 작업을 위해 스크립트에는 3가지 입력이 필요합니다.
- MySQL 호스팅
- MySQL 사용자 이름
- MySQL 비밀번호
왠지 read
입력할 때마다 올바른 변수에 저장되는데, 내용은 제가 저장한 변수 이름이고 첫 글자가 없습니다. 왜 이런 일이 발생하는지 알 수 없는 것 같습니다.
이것은 Makefile
:
SHELL := /bin/bash
default:
@echo "Welcome!";\
echo -n "Please enter the MySQL host (default: localhost):";\
read host;\
host=${host:-localhost};\
echo -n "Please enter the MySQL username:";\
read username;\
echo -n "Please enter the MySQL password:";\
read -s password;\
mv includes/config.php.example includes/config.php 2>/dev/null;true;\
sed 's/"USER", ""/"USER", "$(username)"/g' includes/config.php > includes/config.php;\
sed 's/"PASSWORD", ""/"PASSWORD", "$(password)"/g' includes/config.php > includes/conf$
echo $username;\
echo $password;\
mysql -u "$username" -p"$password" codeday-team < ./codeday-team.sql;\
echo "Configuration complete. For further configuration options, check the config file$
exit 0;
출력은 다음과 같습니다
Welcome!
Please enter the MySQL host (default: localhost):
Please enter the MySQL username:<snip>
Please enter the MySQL password:sername
assword
ERROR 1045 (28000): Access denied for user 'sername'@'localhost' (using password: YES)
Configuration complete. For further configuration options, check the config file includes/config.php
보시다시피 sername
및 가 출력됩니다 assword
. 이건 평생 고칠 수 없어!
이 게시물의 목적은 read
버그를 해결하는 것이지만 제안, 버그 보고서 또는 제안 사항이 있으면 감사하겠습니다. 나는 그들에게 보상을 줄 수도 있습니다.
당신의 도움을 주셔서 감사합니다!
답변1
make
거기에 쉘과 변수를 혼합하고 있습니다 . make
쉘과 둘 다 $
해당 변수를 사용합니다.
Makefile에서 변수는 단일 문자 변수이거나 $(var)
셸 에서 나타 납니다.$v
$var
${var}
$var
하지만 Makefile에 작성하면 make
로 이해됩니다 $(v)ar
. 리터럴을 셸에 전달하려면 , in 또는 로 $
입력해야 셸의 or가 됩니다.$$
$$var
$${var}
$var
${var}
또한 make
을 실행 sh
하면 bash
코드(편집하다, 위의 내용을 놓쳐서 죄송합니다 . 많은 시스템에는 전혀 포함 SHELL := /bin/bash
되어 있지 않으므로 (GNU 전용 인 경우 ) 해당 구문을 사용해야 합니다 . , / 문법이지 구문이 아닙니다 .bash
/bin
bash
:=
sh
echo -n
read -s
zsh
bash
sh
zsh
이를 수행하려면 / bash
스크립트를 추가하고 에 빌드 종속성을 추가하는 것이 더 좋습니다 bash
. 그것은 다음과 같습니다:
#! /usr/bin/env bash
printf 'Welcome\nPlease enter the MySQL host (default: localhost): '
read host || exit
host=${host:-localhost}
printf "Please enter the MySQL username: "
read username || exit
printf "Please enter the MySQL password:"
IFS= read -rs password || exit
printf '\n'
mv includes/config.php.example includes/config.php 2>/dev/null
repl=${password//\\/\\\\}
repl=${repl//&/\\&}
repl=${repl//:/\\:}
{ rm includes/config.php &&
sed 's/"USER", ""/"USER", "'"$username"'"/g
s:"PASSWORD", "":"PASSWORD", "'"$repl"'"/g' > includes/config.php
} < includes/config.php || exit
mysql -u "$username" -p"$password" codeday-team < ./codeday-team.sql || exit
echo "Configuration complete. For further configuration options, check the config file"
더 많은 문제를 해결합니다.
-r
사용자가 비밀번호에 백슬래시를 사용할 수 있도록 하려면 비밀번호를 읽을 때 이를 수행해야 합니다.IFS=
사용자가 공백으로 시작하거나 끝나는 비밀번호를 갖도록 허용하려면 다음이 필요합니다.- 사용자 이름에도 동일하게 적용되지만 여기서는 사용자가 사용자 이름에 어리석은 것을 사용하지 않을 것이며 공백 제거 및 백슬래시 처리가 /feature/로 간주될 수 있다고 가정합니다.
- 당신의
;true
노력은mv
당신이 생각하는 대로 이루어지지 않습니다.errexit
이 옵션의 효과는 취소되지 않습니다 (make
호출 shell 을 사용하는 구현 의 경우-e
). 당신에게 필요한 것은 입니다||true
. 여기서는errexit
필요한 경우 자체 오류 처리를 사용하거나 수행 하지 않습니다|| exit
. &
백슬래시 와s:pattern:repl:
구분 기호(여기 )를 피해야 합니다:
. 그렇지 않으면 작동하지 않습니다(그리고 불쾌한 부작용이 있을 수 있습니다).sed ... < file > file
시작하기 전에 잘리므로 이 작업을 수행할 수 없습니다file
.sed
일부sed
구현에서는-i
or-i ''
옵션을 지원합니다. 또는perl -pi
.perl -pi
여기를 이용하면 더 좋을 것 같아요예하나는 입력이고 마지막 하나는 출력입니다.
여전히 더 이상 질문이 해결되지 않습니다.
config.php
현재 권한에서 파생된 권한으로 새 권한이 생성됩니다umask
.전 세계에서 읽을 수 있는실행중인 사용자가 소유합니다make
. 디렉토리가 달리 제한되지 않은 경우umask
파일에 민감한 정보가 포함되어 있으므로 소유권을 조정 및/또는 변경해야 할 수도 있습니다.includes
- 비밀번호에
"
문자가 포함되어 있으면 비밀번호가 손상되었을 수 있습니다(이번에는php
). 오류를 반환하여 이를 억제하거나php
해당 파일에 대한 올바른 구문으로 다른 이스케이프 레이어를 추가하려고 합니다. 백슬래시와 비슷한 문제가 발생할 수 있으며 ASCII가 아닌 문자나 제어 문자를 제외할 수도 있습니다. 명령줄에서 비밀번호를 전달하는 것은
mysql
일반적으로 비밀번호가 출력에 표시된다는 의미이므로 좋지 않은 생각입니다ps -f
. 사용하는 것이 가장 좋습니다:mysql --defaults-file=<( printf '[client]\nuser=%s\npassword="%s"\n' "$username" "$password") ...
printf
내장되어 있기 때문에ps
출력에는 나타나지 않습니다.$host
이 변수는 사용되지 않습니다.- 사용자에게 이와 같은 메시지를 표시하는 것은 스크립트를 쉽게 자동화할 수 없음을 의미합니다. 매개변수에서 입력을 얻거나 환경 변수를 사용할 수 있습니다(비밀번호에 더 좋음).
답변2
Makefile의 어떤 기능도 사용하고 있지 않습니다. 단일 셸에 이러한 줄을 작성하려고 합니까?
다음으로 사용하는 Makefile에서
echo $username;\
echo $password;\
make는 (빈 변수) + (문자열) $username
로 해석됩니다 .$u
sername
Makefile에 보관하고 싶다면 $username
.$$username