2017-11-26 11 views
1

쉘에서 참조, 디렉토리 이름 : 나는 루비의 system 호출을 참조하면왜 루비의`system`은`shellescape`가 아닌 첫 번째 인수입니까? 괄호 등으로

/tmp/\(example\) 

, 나는 탈출해야 :

/tmp/(example) 

필요가 같이 이스케이프 할 그것들이 첫 번째 주장인지 아닌지에 달려있다.

  • 첫 번째 인수로 이스케이프 처리되지 않은 디렉토리. 실패.

    system('/tmp/(example)/script') 
    #>> sh: -c: line 0: syntax error near unexpected token `example' 
    #>> sh: -c: line 0: `/tmp/(example)/script' 
    #=> false 
    
  • 첫 번째 인수로 이스케이프 처리 된 디렉토리. 성공.

    system('/tmp/(example)/script'.shellescape) 
    #=> true 
    
  • 두 번째 인수로 이스케이프 처리되지 않은 디렉토리. 성공.

    system('touch', '/tmp/(example)/script') 
    #=> true 
    
  • 두 번째 인수로 이스케이프 처리 된 디렉토리. 실패.

    system('touch', '/tmp/(example)/script'.shellescape) 
    #>> touch: /tmp/\(example\)/script: No such file or directory 
    #=> false 
    

system 모든 인수하지만 명령 (첫 번째 인수)의 이름을 탈출 것으로 보인다.

system("#{__dir__}/something") 
  1. system이 방식으로 작동 않습니다 그 누구의 명령 상대 경로 등을 보유하고 스크립트의 문제인가?
  2. 모든 것을 탈출 할 수있는 기본 옵션이 있습니까?

답변

1

맹목적으로 전체 명령을 #shellescape으로 전송하는 것은 거의 불가능합니다. 이것을 고려해보십시오 :

> puts '(pancakes) --house'.shellescape 
\(pancakes\)\ --house 

확실하게, 당신은 아마 괄호를 벗어나길 원할 것입니다. 그러나 확실히 당신은 그 공간을 벗어나고 싶지 않을 것입니다. 옳은 일을하고 DWIM (Do What I Mean)을하기 위해서 #system은 어느 부분이 빠져 나가야하는지, 어떤 부분이 빠져 나가서는 안되는지를 짐작할 필요가 있습니다.

해결 방법은 절대로 쉘을 호출하지 않도록 #system이라는 단일 인수 형식을 사용하지 않는 것입니다.

system('/bin/ls -l') 

다음 쉘이 그 명령 줄 호출되고 쉘이 명령을 호출하기 전에 구문 분석 할 수있다 : 당신은 같은 것을 말합니다. 더 걱정 탈출이 없다, 그래서
system('/bin/ls', '-l') 

다음 /bin/ls 직접 호출

, 아니 쉘이 포함되지 않은 : 당신이 말하고자합니다.

system('/bin/ls', '--') 
system(['/bin/ls', '--']) 

인수없이 쉘없이 명령을 호출하지만, 아마도 이들은 매우 일반적이지 그리고 당신이 당신이 무엇을 다루고 있는지 알고 때 수동 이스케이프 다시 떨어질 수 : 물론, 때로는 바보 같은 것들에 이르게 와.

외부 프로그램과 상호 작용해야 할 때 #system이 존재하지 않고 바로 Open3으로 이동하는 경향이 있습니다. Open3은 조금 더 장황하지만 인터페이스 IMO를 사용하기 쉽고 청소기가 있습니다.

비슷한 인수가 명령을 실행하고 출력을 캡처하는 데 사용됩니다.


두 번째 예 : 두 번째 인수에 괄호가 특별한 의미가 없다 그래서 쉘이 호출되지 않기 때문에

# Unescaped directory as second argument. Success. 
> system('touch', '/tmp/(example)/script') 
=> true 

작품.

세 번째 예 :

# Escaped directory as second argument. Failure. 
> system('touch', '/tmp/(example)/script'.shellescape) 
touch: /tmp/\(example\)/script: No such file or directory 
=> false 

이 같은 이유로 실패 : 어떤 쉘이 더 이스케이프를 의미합니다.

+0

"나는'# system '이 존재하지 않고 ['Open3'] (http://ruby-doc.org/stdlib-2.4.2/libdoc/open3/rdoc/Open3)로 바로가는 경향이 있습니다. .html) (...) ". 'Open3'은이 상황에서 똑같이 동작합니다. 명령을 실행하고 출력을 신경 쓸 필요가 없으면'system'을 사용하고, 다른 모든 경우에는'Open3 '을 사용하는 경향이 있습니다. – user137369