테이블을 업데이트하기 위해 작은 데이터베이스에 대해 sqlite3 쿼리를 실행하려고 합니다. 스크립트가 더 복잡하기는 하지만 테스트를 위해 다음 변수를 설정했습니다.
DN=123
UP=123
downlocalip=10.1.2.3
downremoteip=123
uplocalip=123
upremoteip=123
그런 다음 다음 명령을 실행하여 테이블을 업데이트합니다.
sqlite3 /var/www/server/newserverstats.db "UPDATE stats SET downspeed='''$DN''', upspeed='''$UP''', downlocalip='''$downlocalip''', downremoteip='''$downremoteip''', uplocalip='''$uplocalip''', upremoteip='''$upremoteip''' WHERE primkey=1"
구문 오류가 발생합니다.
Error: near ".2": syntax error
내가 설정하면로컬 IP 다운로드10.1에서만 잘 작동하므로 추가 소수점을 좋아하지 않습니다.
테이블 자체에서 유형을 텍스트로 설정했기 때문에 그것이 중요하지 않다고 가정합니까?
테이블에 대한 pragma 출력:
0|primkey|integer|0||1
1|downspeed|integer|1||0
2|upspeed|integer|1||0
3|downlocalip|text|1||0
4|downremoteip|text|1||0
5|uplocalip|text|1||0
6|upremoteip|text|1||0
다양한 견적 설정을 시도했지만 내가 뭘 잘못하고 있는지 알 수 없습니다.
어떤 아이디어가 있나요?
편집하다:
아래 의견을 바탕으로 시도한 전체 명령은 다음과 같습니다.
/usr/bin/ssh [email protected] 'sqlite3 /var/www/server/newserverstats.db "UPDATE stats SET downspeed=$DN, upspeed=$UP, downlocalip="$downlocalip", downremoteip="$downremoteip", uplocalip="$uplocalip", upremoteip="$upremoteip" WHERE primkey=1"'
또는
/usr/bin/ssh [email protected] 'sqlite3 /var/www/server/newserverstats.db "UPDATE stats SET downspeed=$DN, upspeed=$UP, downlocalip='$downlocalip', downremoteip='$downremoteip', uplocalip='$uplocalip', upremoteip='$upremoteip' WHERE primkey=1;"'
둘 다 나에게 다음과 같은 오류를 제공합니다.
Error: near ",": syntax error
새로운 명령, 더 자세히:
ssh [email protected] sqlite3 /var/www/server/newserverstats.db <<END_SQL
UPDATE stats
SET downspeed=$DN,
upspeed=$UP,
downlocalip="$downlocalip",
downremoteip="$downremoteip",
uplocalip="$uplocalip",
upremoteip="$upremoteip"
WHERE primkey=1
END_SQL
테스트 스크립트의 한 줄로 다시 접습니다.
#!/bin/bash -x
DN=123
UP=123
downlocalip=10.1.2.3
downremoteip=123
uplocalip=123
upremoteip=123
sql="UPDATE stats SET downspeed=$DN, upspeed=$UP, downlocalip="$downlocalip", downremoteip="$downremoteip", uplocalip="$uplocalip", upremoteip="$upremoteip" WHERE primkey=1"
echo $sql
ssh [email protected] sqlite3 /var/www/server/newserverstats.db "$sql"
그러면 다음과 같은 응답이 제공됩니다.
UPDATE stats SET downspeed=123, upspeed=123, downlocalip=10.1.2.3, downremoteip=123, uplocalip=123, upremoteip=123 WHERE primkey=1
sqlite3: Error: too many options: "stats"
Use -help for a list of options.
답변1
문제는 텍스트 필드의 문자열 참조에 있습니다.
여기에 있는 문서를 사용하세요(더 멋진 문장을 작성할 수 있게 해줍니다):
sqlite3 database <<END_SQL
UPDATE stats
SET downspeed=$DN,
upspeed=$UP,
downlocalip="$downlocalip",
downremoteip="$downremoteip",
uplocalip="$uplocalip",
upremoteip="$upremoteip"
WHERE primkey=1
END_SQL
이는 변수 값이 올바르게 삭제되었으며 SQL 주입 취약점이 발생하지 않았음을 알 수 있도록 변수 값을 완전히 제어할 수 있다고 가정합니다.
댓글에서:
SSH를 통해 이 작업을 수행합니다.
ssh user@server sqlite3 database <<END_SQL
UPDATE stats
SET downspeed=$DN,
upspeed=$UP,
downlocalip="$downlocalip",
downremoteip="$downremoteip",
uplocalip="$uplocalip",
upremoteip="$upremoteip"
WHERE primkey=1
END_SQL
답변2
주요 문제는 각 변수 앞뒤에 하나의 작은따옴표가 아닌 세 개의 작은따옴표를 사용한다는 것입니다. 이는 꼭 필요한 것은 아닙니다. 실제로는 작동하지 않습니다.
실제로 인용되지 않았기 때문에 IP 주소에 오류가 발생하므로 $downlocalip
sqlite3은 이를 텍스트 문자열 대신 부동 소수점으로 해석하려고 합니다... 부동 소수점에는 소수점이 두 개가 없습니다.
또 다른 작은 문제는 정수 필드( downspeed
및 ) upspeed
의 값 주위에 작은따옴표를 넣는 것 입니다.
이 시도:
sqlite3 /var/www/server/newserverstats.db "UPDATE stats SET downspeed=$DN,
upspeed=$UP, downlocalip='$downlocalip', downremoteip='$downremoteip',
uplocalip='$uplocalip', upremoteip='$upremoteip' WHERE primkey=1;"
이 문자열의 작은따옴표는 다음과 같습니다.~에큰따옴표는 쉘이 변수를 확장하는 것을 방해하지 않습니다. 큰따옴표 안에는 특별한 의미가 없으며 단지 텍스트의 일부일 뿐입니다. 큰따옴표 안의 변수는 특별한 의미를 가지므로 의도한 대로 확장하세요.
또는 Kusalananda의 답변에 있는 heredoc을 사용하세요. 더 읽기 쉽습니다.
그런데 sqlite 작업을 많이 수행하는 경우 자리 표시자 값을 지원하는 sqlite 라이브러리 모듈이 있는 언어로 스크립트를 작성하는 것이 가장 좋습니다. 예를 들어, 두 가지 모두 sqlite3 및 기타 SQL 데이터베이스 작업을 위한 뛰어난 라이브러리를 perl
갖추고 있습니다 . python
이러한 라이브러리를 사용하여 코드를 작성하면 변경 사항이 거의 없이 다른 데이터베이스(예: postgresql 또는 mysql)와 작동할 수 있습니다.