큰따옴표 명령 내에서 작은따옴표 하위 명령 내에서 작은따옴표를 이스케이프합니다.

큰따옴표 명령 내에서 작은따옴표 하위 명령 내에서 작은따옴표를 이스케이프합니다.

문제는 다음과 같이 간단합니다.

watch "psql -d postgresql://user:pass@host:5432/dbname -c 'select id,name from table where name <> 'not available' order by id;'"

'not available'비교는 작은따옴표로 묶어야 합니다.있는 그대로포스트그레스의 경우. 그러나 psql 명령(즉, select...) 자체가 이미 작은 따옴표로 묶여 있고 psql감시를 호출하는 데 필요한 큰 따옴표 안에 있기 때문에 이러한 작은 따옴표를 적절하게 이스케이프하는 방법을 찾을 수 없습니다 .

이 문제를 해결하는 방법? 나는 하나 이상의 큰따옴표/작은따옴표를 사용하여 이러한 작은따옴표를 이스케이프 처리함으로써
가능한 거의 모든 구문 오류를 보았습니다 .\

답변1

작은따옴표 안에는 작은따옴표를 이스케이프할 수 없습니다. 그러나 다음을 사용하여 가짜로 만들 수 있습니다.

'\''

설명: 이것은 닫는 작은 따옴표(즉, 현재 따옴표 끝)이고 그 뒤에 이스케이프된 작은 따옴표가 오고 다시 시작 작은 따옴표가 옵니다. 그것은 'a'b'c'(인용된 a다음 인용되지 않은 b다음 인용된 것 c- 모두 함께, 단지 abc... 그리고 'a'\''b'단지 a'b) 와 동일하게 작동합니다.

watch "psql -d postgresql://user:pass@host:5432/dbname -c \
  'select id,name from table
   where name <> '\''not available'\''
   order by id;'"

(가독성을 높이기 위해 줄 바꿈이 추가되었습니다. sql 명령은 줄 바꿈이 있든 없든 동일하게 작동합니다.)


참고: postgres(또는 sqlite 또는 mysql 등)를 사용할 때는 자리 표시자를 지원하는 언어를 사용하는 것이 가장 좋으므로 인용에 대해 걱정할 필요가 없습니다. CLI는 대화형 쿼리 및 일부 스크립팅(sh가 아닌 SQL)에 적합하지만 sh에서 SQL 코드를 전달하는 데 필요한 중첩 참조는 다루기 힘들고 오류가 발생하기 쉽습니다(불가능하지는 않으며 다른 언어보다 더 복잡함). 작업이 훨씬 더 어렵습니다. ).

예를 들어 펄에서는데이터베이스 인터페이스(보일러플레이트 로그인 콘텐츠는 포함하지 않았고 준비된 문과 자리 표시자만 선택했습니다):

# you could use string literals, but i'll use some
# variables for this example
my $exclude = 'not available';
my $sql = 'select id,name from table where name <> ? order by id';

my $sth = $dbh->prepare($sql);
$sth->execute($exclude);

이는 ?자리 표시자이며 DBI는 이를 귀하가 제공한 값으로 대체합니다. 인용하세요.자동으로필요한 경우 열의 데이터 유형에 따라 다릅니다. 즉, 열의 데이터를 제공하고 인용 및 이스케이프에 대해 걱정하도록 하십시오.

그런데, 여러 개의 매개변수를 가질 수 있습니다. 올바른 유형의 매개변수를 올바른 순서로 제공하기만 하면 됩니다. 또한 일부 DBI 드라이버는 다음을 포함합니다.DBD::Pg:name- 예를 들어 명명된 자리 표시자나 번호가 매겨진 자리 표시자를 사용할 수 있습니다 $1. $2- 이는 쉘 위치 매개변수와 동일해 보이고 거의 동일한 방식으로 작동하지만 그렇지 않습니다. SQL 문에서는 자리 표시자입니다.

my $sql = 'select id,name from table where name <> $1 order by id';

쉘은 다른 프로그램에 데이터 및/또는 파일 이름을 입력하고 다른 프로그램의 실행을 조정하는 것 이상의 작업을 수행하는 모든 언어에 적합하지 않은 언어입니다. 인용, 공백, 단어 분리기 등과 같은 문제에 주의를 기울여야 하기 때문에 적당히 복잡한 것조차도 PITA가 될 것입니다. ssh명령 내에서 find .. -exec sh -c '...' {} +따옴표를 중첩하거나 여러 수준의 따옴표를 중첩해야 하는 다른 많은 상황에서 동일한 문제가 발생합니다 .

답변2

구분 기호를 사용하여 이스케이프를 방지하는 것도 가능합니다.

psql  "postgresql://[email protected]:5432/db1" <<EOF 
select id,name from table where name <> 'not available' order by id;
EOF

관련 정보