쉘 스크립트에서 MySQL 명령을 실행하는 방법은 무엇입니까?


131

셸 스크립트를 통해 SQL 명령을 실행하여 자동화되도록하려면 어떻게해야합니까?

쉘 스크립트를 사용하여 SQL 파일로 수집 한 데이터를 복원하고 싶습니다. 서버에 연결하고 데이터를 복원하고 싶습니다. 이 명령은 SSH 명령 줄을 통해 별도로 실행될 때 작동합니다.

이것이 내가 사용하는 명령입니다.

mysql -h "server-name" -u root "password" "database-name" < "filename.sql"

이것은 파일을 만들고 ds_fbids.sqlmysql에 파이프 하는 쉘 스크립트 코드입니다 .

perl fb_apps_frm_fb.pl
perl fb_new_spider.pl ds_fbids.txt ds_fbids.sql
mysql -h dbservername -u username -ppassword dbname < ds_fbids.sql

이를 수행하는 올바른 방법은 무엇입니까?

답변:


176

-p비밀번호를 보내 려면 플래그 를 사용해야 합니다. 그리고 -p암호 사이에 공백이 없어야하기 때문에 까다 롭습니다 .

$ mysql -h "server-name" -u "root" "-pXXXXXXXX" "database-name" < "filename.sql"

-pmysql 클라이언트가 대화식으로 비밀번호를 묻는 프롬프트를 표시 한 후 공백을 사용 하면 다음 명령 인수가 database-name으로 해석됩니다.

$ mysql -h "server-name" -u "root" -p "XXXXXXXX" "database-name" < "filename.sql"
Enter password: <you type it in here>
ERROR 1049 (42000): Unknown database 'XXXXXXXX'

실제로 ~ / .my.cnf에 사용자와 비밀번호를 저장하는 것을 선호하므로 명령 줄에 전혀 입력하지 않아도됩니다.

[client]
user = root
password = XXXXXXXX

그때:

$ mysql -h "server-name" "database-name" < "filename.sql"

당신의 의견을 다시 :

위와 같은 배치 모드 mysql 명령을 명령 줄과 셸 스크립트에서 항상 실행합니다. 정확한 스크립트 나 오류 출력을 공유하지 않았기 때문에 쉘 스크립트의 문제점을 진단하기가 어렵습니다. 위의 원래 질문을 수정하고 무엇이 잘못되었는지에 대한 예를 제공하는 것이 좋습니다.

또한 쉘 스크립트 문제를 해결할 때 -x플래그를 사용 하므로 각 명령이 어떻게 실행되는지 볼 수 있습니다.

$ bash -x myscript.sh

빠른 답변 감사합니다. 커맨드 라인 자체에 암호를 넣어 피곤했습니다. 실제 문제는이 명령을 .sh 파일에 넣고이 셸 스크립트를 실행하는 것입니다. 파일의 명령은 명령 줄에서 실행되지 않지만 명령 줄에서 명령 만 실행할 때 동일한 명령이 완벽하게 작동합니다.
MUFC

+ mysql -h dbservername -u user-name -ppassword dbname</br> : No such file or directoryids.sql</br> + $'\r' : command not found2:이것은 내가 가진 오류 메시지입니다
MUFC

그렇다면 현재 작업 디렉토리가 ids.sql 파일이있는 곳이 아니라고 추측합니다. 또한 스크립트에 줄 바꿈을 포함했을 수 있습니다.
Bill Karwin

모든 명령 후에 쉘 스크립트에 새 줄이 포함되어 있습니다. 내 셸 스크립트에 포함 된 모든 것은 3 개의 명령 줄 명령으로, 별도로 실행하고 싶지 않으므로 개입하지 않고 셸 스크립트를 작성하여 모든 줄마다 줄 바꿈 문자를 넣습니다. 문제가 있습니까?
MUFC

-p비밀번호가 null이거나 빈 문자열 인 경우 피하는 것이 가장 좋습니다. 게시물을 업데이트 할 수 있습니까? :)
James Oravec

118

이 구문을 사용하십시오.

mysql -u $user -p$passsword -Bse "command1;command2;....;commandn"

8
나는 구글 에서이 페이지에 방문했고 이것이 내가 예상 한 해결책입니다 (질문의 제목과 일치).
Janaka R Rajapaksha

15
매뉴얼의 옵션에 대한 자세한 내용은 다음과 같습니다. -B 는 탭을 열 구분 기호로 사용하여 배치를 인쇄하고 각 행을 새 행에 인쇄하는 것입니다. 이 옵션을 사용하면 mysql은 기록 파일을 사용하지 않습니다. 배치 모드는 비표 형식의 출력 형식과 특수 문자를 이스케이프 처리합니다. -s 는 자동 모드입니다. 더 적은 출력을 생성합니다. -e 는 문장을 실행하고 종료합니다
wranvaud

당신의 도움을 주셔서 감사합니다! :)
haotang

heredoc과 함께 실행할 수 있습니까?
zx1986

1
@ zx1986 예, 아니오, HEREDOC. 사용 방법에 따라 다릅니다. "command1;command2;....;commandn"이 답변 의 일부 를 대체하는 데는 사용할 수 없습니다. 이를 사용하여 OP의 구문에서 경로 재 지정된 파일 사용을 대체 할 수 있습니다. 이 질문에 대한 답변 에서 해당 문제를 해결했습니다 .
Chindraba

45

이전의 모든 대답은 훌륭합니다. 실행하려는 간단한 한 줄 sql 명령 인 경우 -e 옵션을 사용할 수도 있습니다.

mysql -h <host> -u<user> -p<password> database -e \
  "SELECT * FROM blah WHERE foo='bar';"

double ( "") 따옴표 안의 쿼리는 내가해야 할 일이었습니다. 감사합니다
user3132107

알다시피 쿼리 끝에 세미콜론을 포함해야합니까?
Lori

19

SQL 스크립트를 실행하는 방법은 다음 구문을 사용하십시오.

mysql --host= localhost --user=root --password=xxxxxx  -e "source dbscript.sql"

호스트를 localhost로 사용하는 경우 언급 할 필요가 없습니다. 이것을 사용할 수 있습니다 :

mysql --user=root --password=xxxxxx  -e "source dbscript.sql"

이것은 Windows 및 Linux에서 작동합니다.

비밀번호 내용에 !(느낌표)가 있으면 \그 앞에 (백 슬래시)를 추가해야 합니다.


1
데이터베이스를 지정하는 방법? -e "use abc; source dbscript.sql"과 같이 -e 안에 있어야합니까?
Abdul Muneer 2016 년

9

질문의 핵심은 이미 여러 번 대답되었지만 방금 셸 스크립팅과 SQL 모두에서 백틱이 비닝된다고 생각했습니다. 테이블이나 데이터베이스 이름을 지정하기 위해 SQL에서 사용해야하는 경우 다음과 같이 쉘 스크립트에서 이스케이프해야합니다.

mysql -p=password -u "root" -Bse "CREATE DATABASE \`${1}_database\`;
CREATE USER '$1'@'%' IDENTIFIED BY '$2';
GRANT ALL PRIVILEGES ON `${1}_database`.* TO '$1'@'%' WITH GRANT OPTION;"

물론, 사용자 입력을 신뢰하지 않는 한 연결된 사용자 입력 (통과 인수)을 통해 SQL을 생성하면 안됩니다. MySQL로.


5
mysql -h "hostname" -u usr_name -pPASSWD "db_name" < sql_script_file

(에 대한 전체 경로 사용 sql_script_file 필요한 경우 )

출력을 파일로 리디렉션하려면

mysql -h "hostname" -u usr_name -pPASSWD "db_name" < sql_script_file > out_file

@Gus, 우선 귀중한 의견에 감사드립니다. 그것은 나를 위해 매력처럼 작동했습니다. 출력을 Excel 또는 .csv 파일로 만들고 싶습니다. 어떻게하면 될까요? 미리 감사드립니다.
Ash_and_Perl

@Ash_and_Perl 나는이 답변 만 편집했습니다. 덩굴 감사합니다. 그의 대답입니다. 본인이 궁금한 점이 있고 스스로 해결책을 찾은 경우 질문을 작성하는 것이 좋습니다. 그렇게하면 시도한 것, 실패한 방법, 사람들이 당신에게 완전하고 완전한 답변을 줄 수 있습니다 (그리고 그 점을 얻을 수 있습니다!).
거스

5

잊었 -p거나 --password=후자가 더 잘 읽을 수 있습니다.

mysql -h "$server_name" "--user=$user" "--password=$password" "--database=$database_name" < "filename.sql"

자격 증명 / 이름에 공백이나 셸 특수 문자가 포함되어 있지 않은 경우 따옴표는 필요하지 않습니다.

맨 페이지도 명령 줄에 자격 증명을 제공하는 것이 안전하지 않다고 말합니다. 따라서 my.cnf에 대한 Bill의 조언을 따르십시오.


4

앞에서 설명한대로 -p를 사용하여 서버에 비밀번호를 전달할 수 있습니다.

그러나 나는 이것을 추천한다 :

mysql -h "hostaddress" -u "username" -p "database-name" < "sqlfile.sql"

비밀번호가 없습니다. 그런 다음 암호를 묻습니다. 그런 다음 암호를 입력하여 서버 명령 줄 기록에 로그인하지 않도록합니다.

이것은 기본적인 보안 조치입니다.

보안이 중요하지 않은 경우 데이터베이스 사용자로부터 비밀번호를 일시적으로 제거합니다. 그런 다음 가져 오기 후 다시 추가하십시오.

이렇게하면 동일한 비밀번호를 공유하는 다른 계정이 손상되지 않습니다.

또한 쉘 스크립트에서 가져 오려고하는 파일이 실제로 존재하는지 확인 / 대기하지 않는 것으로 보입니다. 펄 스크립트가 아직 완료되지 않았을 수 있습니다.


1
질문의 "자동화 된"부분을 놓쳤으며 비밀번호를 일시적으로 제거하는 것은 정말 나쁜 생각입니다.
PointedEars

"복원"과 "자동화"로 읽었습니다. "자동화되었지만 영원히"는 아닙니다. 그러나 내가 말했듯이 "보안이 문제가되지 않는다면". 동의합니다-정말 나쁜 생각입니다.
Sterling Hamilton

혼란을 일으켜서 죄송합니다. 내가 자동화 한 의미는 .sql 파일을 생성하는 데 사용되는 두 개의 perl 스크립트가 있지만 해당 파일을 DB에 덤프하는 명령은 쉘 스크립트에 의해 실행되지 않지만 해당 명령을 실행하면 절대적으로 파일로 작동한다는 것입니다 명령 행에서. 명령 줄에서 해당 명령을 실행하고 셸 스크립트 자체를 통해 실행하려는 노력을 완화하고 싶습니다.
MUFC

1
Vaibav : 질문에 실제 쉘 스크립트를 넣을 수 있다면 더 도움이 될 수 있습니다.
Sterling Hamilton

perl fb_apps_frm_fb.pl</br> perl fb_new_spider.pl ds_fbids.txt ds_fbids.sql` </br>mysql -h dbservername -u username -ppassword dbname < ds_fbids.sql
MUFC


3

"자동화"생성 된 수입하는 과정을 .sql통해 파일을 통과하려고에 숨겨진 할 수있는 모든 트랩을 피하면서 파일을, stdinstdout단지 생성 된 실행하기 위해 MySQL을 말할 .sql사용하여 파일 SOURCE의 MySQL의 명령을 사용합니다.

짧고,하지만 우수한에서 구문 대답은 ,에서 Kshitij 수드 , 가장 좋은 출발점을 제공합니다. 간단히 말해서 Kshitij Sood의 구문에 따라 OP의 명령을 수정하고 해당 명령을 다음 명령으로 바꿉니다 SOURCE.

#!/bin/bash
mysql -u$user -p$password $dbname -Bse "SOURCE ds_fbids.sql
SOURCE ds_fbidx.sql"

데이터베이스 이름이 생성 된 .sql파일에 포함 된 경우 명령에서 삭제할 수 있습니다.

여기서 가정은 생성 된 파일이 자체 파일로 유효하다는.sql입니다. 쉘에서 파일을 경로 재 지정, 파이프 또는 기타 방식으로 처리하지 않아도 쉘로 인해 생성 된 출력에서 ​​문자를 이스케이프 처리 할 필요가 없습니다. .sql물론 파일 에서 이스케이프해야 할 것에 관한 규칙은 여전히 적용됩니다.

명령 줄이나 my.cnf파일 등 의 암호와 관련된 보안 문제를 처리하는 방법 은 다른 답변으로 잘 해결되었습니다. 내 마음에 드는 대답 에서, 대니 , 커버를 처리 할 때 문제를 처리하는 방법을 포함하는, cron작업, 또는 다른 것.


내가 언급 한 짧은 대답에 대한 의견 (질문?) 을 해결하려면 : 아니오, 해당 쉘 명령이 제공되므로 HEREDOC 구문과 함께 사용할 수 없습니다. I / O 리디렉션은 HEREDOC를 기반으로하기 때문에 HEREDOC은 옵션 없이 리디렉션 버전 구문에 사용할 수 있습니다 -Bse. HEREDOC의 기능이 필요한 경우 .sql파일이 임시 파일 인 경우에도 파일을 작성하는 데 사용하고 해당 파일을 "명령"으로 사용하여 MySQL 배치 라인에서 실행하는 것이 좋습니다.

#!/bin/bash
cat >temp.sql <<SQL_STATEMENTS
...
SELECT \`column_name\` FROM \`table_name\` WHERE \`column_name\`='$shell_variable';
...
SQL_STATEMENTS
mysql -u $user -p$password $db_name -Be "SOURCE temp.sql"
rm -f temp.sql

쉘 확장으로 인해 HEREDOC 내에서 쉘 및 환경 변수를 사용할 수 있습니다. 단점은 각각의 백틱을 피해야한다는 것 입니다. MySQL은 식별자를 구분 기호로 사용하지만 문자열을 먼저 얻는 쉘은이를 실행 가능한 명령 구분 기호로 사용합니다. MySQL 명령의 단일 백틱에서 탈출을 놓치면 모든 것이 오류로 폭발합니다. HEREDOC에 대해 인용 된 LimitString을 사용하여 전체 문제를 해결할 수 있습니다.

#!/bin/bash
cat >temp.sql <<'SQL_STATEMENTS'
...
SELECT `column_name` FROM `table_name` WHERE `column_name`='constant_value';
...
SQL_STATEMENTS
mysql -u $user -p$password $db_name -Be "SOURCE temp.sql"
rm -f temp.sql

그런 식으로 쉘 확장을 제거하면 백틱 및 기타 쉘 특수 문자를 벗어날 필요가 없습니다. 또한 쉘 및 환경 변수를 사용하는 기능도 제거합니다. 이는 쉘 스크립트 내부에서 HEREDOC을 사용하여 얻을 수있는 이점을 거의 제거합니다.

다른 옵션은 Bash에서 허용되는 여러 줄로 묶인 문자열을 배치 구문 버전 ()과 함께 사용하는 것 -Bse입니다. 나는 다른 껍질을 알지 못하기 때문에 껍질이 잘 작동하는지 말할 수 없습니다. 어쨌든 다른 MySQL 명령처럼 종료 되지 않고 한 줄에 하나만 허용 되기 때문에 어쨌든 명령으로 둘 이상의 .sql파일 을 실행하기 위해 이것을 사용해야합니다 . 여러 줄로 된 문자열은 셸 확장에 일반적인 영향으로 작은 따옴표 나 큰 따옴표로 묶을 수 있습니다. 또한 HEREDOC 구문을 사용하여 백틱 등에 사용하는 것과 동일한 경고가 있습니다.SOURCE;

잠재적으로 더 나은 해결책은 스크립트 언어, Perl, Python 등을 사용 .sql하여 OP와 마찬가지로 파일 을 작성 SOURCE하고 맨 위에 간단한 명령 구문을 사용하여 파일을 작성하는 것입니다. 스크립팅 언어는 셸보다 문자열 조작에서 훨씬 우수하며 대부분 MySQL을 처리 할 때 필요한 인용 및 이스케이프 처리를위한 내장 프로 시저가 있습니다.


2

cron에서 사용되는 쉘 스크립트에서 mysql에 액세스 할 때 고려해야 할 중요한 사항은 mysql이 로그인 한 사용자를보고로드 할 .my.cnf를 결정한다는 것입니다.

cron에서는 작동하지 않습니다. 로그인 한 사용자가 실행중인 사용자가 아니기 때문에 su / sudo를 사용하는 경우 혼동 될 수도 있습니다.

나는 다음과 같은 것을 사용한다 :

mysql --defaults-extra-file=/path/to/specific/.my.cnf -e 'SELECT something FROM sometable'

.my.cnf 파일에서 사용자 및 그룹 소유권과 권한이 적절하고 엄격하게 설정되어 있는지 확인하십시오.


1
#!/bin/sh
#Procedures = update
#Scheduled at : Every 00.05 

v_path=/etc/database_jobs
v_cnt=0

MAILTO="indd@abc.in joanson@abc.in sturt@abc.in"
touch "$v_path/db_db_log.log"

#test
mysql -uusername -ppassword -h111.111.111.111 db_name -e "CALL functionName()" > $v_path/db_db_log.log 2>&1
if [ "$?" -eq 0 ]
  then
   v_cnt=`expr $v_cnt + 1`
  mail -s "db Attendance Update has been run successfully" $MAILTO < $v_path/db_db_log.log
 else
   mail -s "Alert : db Attendance Update has been failed" $MAILTO < $v_path/db_db_log.log
   exit
fi

0
mysql_config_editor set --login-path=storedPasswordKey --host=localhost --user=root --password

보안 암호를 사용하여 명령 줄을 어떻게 실행합니까? 구성 편집기를 사용하십시오 !!!

mysql 5.6.6부터는 설정 파일에 비밀번호를 저장하고 다음과 같은 cli 명령을 실행할 수 있습니다.

mysql --login-path=storedPasswordKey ....

--login-path는 변수, 호스트, 사용자 및 비밀번호를 대체합니다. 맞아요!



0

속성 파일에서 데이터를 읽은 다음 쉘 스크립트에서 mysql 스크립트를 실행하는 쉘 스크립트를 작성했습니다. 이것을 공유하면 다른 사람들에게 도움이 될 수 있습니다.

#!/bin/bash
    PROPERTY_FILE=filename.properties

    function getProperty {
       PROP_KEY=$1
       PROP_VALUE=`cat $PROPERTY_FILE | grep "$PROP_KEY" | cut -d'=' -f2`
       echo $PROP_VALUE
    }

    echo "# Reading property from $PROPERTY_FILE"
    DB_USER=$(getProperty "db.username")
    DB_PASS=$(getProperty "db.password")
    ROOT_LOC=$(getProperty "root.location")
    echo $DB_USER
    echo $DB_PASS
    echo $ROOT_LOC
    echo "Writing on DB ... "
    mysql -u$DB_USER -p$DB_PASS dbname<<EOFMYSQL

    update tablename set tablename.value_ = "$ROOT_LOC" where tablename.name_="Root directory location";
    EOFMYSQL
    echo "Writing root location($ROOT_LOC) is done ... "
    counter=`mysql -u${DB_USER} -p${DB_PASS} dbname -e "select count(*) from tablename where tablename.name_='Root directory location' and tablename.value_ = '$ROOT_LOC';" | grep -v "count"`;

    if [ "$counter" = "1" ]
    then
    echo "ROOT location updated"
    fi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.