windows - करन - दूसरे की कॉल कैसे सुने



सीमके: तर्क में दोहरे उद्धरण के साथ execute_process को कैसे कॉल करें? उर्फ कमान से ढूंढने के लिए स्ट्रिंग से मेल खाते लाइनों की गणना करने के लिए (1)

केमके डेवलपर्स के मुताबिक ,
विंडोज की find को सीमके द्वारा सीधे execute_process के द्वारा नहीं कहा जा सकता, क्योंकि CreateProcess API की एक सीमा के कारण और गैर-मानक तरीके से पार्स तर्क find हैं।

इसे अप्रत्यक्ष रूप से हालांकि, एक अस्थायी बैच स्क्रिप्ट बनाकर कहा जा सकता है।

Windows में एक प्रोग्राम के आउटपुट से स्ट्रिंग की घटनाओं की गिनती की मेरी समस्या निम्न तरीके से हल हो गई है:

file(WRITE ${CMAKE_BINARY_DIR}/countLines.bat [[@find /v /c "" %1]])
execute_process(COMMAND <firstCommandPipingSomethingToFind> COMMAND findstr <regular expression> COMMAND countLines.bat WORKING_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_VARIABLE N_MATCHES OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "N_MATCHES=${N_MATCHES}")
file(REMOVE ${CMAKE_BINARY_DIR}/countLines.bat)

बीच में findstr का लाभ यह है कि यह नियमित अभिव्यक्तियों का समर्थन करता है। find लिए मिलान लाइनों की गणना करने के लिए उपयोग किया जाता है

find सामने @ आउटपुट चर में समाप्त होने से स्क्रिप्ट के भीतर कमांड आवंजन को रोकने के लिए है।

मैं एक execute_process भीतर से find लिए आदेश को कॉल करना execute_process

find कमांड का प्रारूप है:

find [/v] [/c] [/n] [/i] [/off[line]] "<String>" [[<Drive>:][<Path>]<FileName>[...]]

इसलिए, स्ट्रिंग को दो बार उद्धृत किया जाना चाहिए। हालांकि, यदि मैं सेमीकैस में करता हूं:

execute_process(COMMAND <firstCommandPipingSomethingToFind> 
                COMMAND find "<myString>" /c
                OUTPUT_VARIABLE MY_COUNT
                OUTPUT_STRIP_TRAILING_WHITESPACE)

मुझे एक त्रुटि मिलती है FIND: Parameter format not correct
अगर मैं दोहरे उद्धरण चिह्नों से बचता हूं, तो मुझे एक त्रुटि मिलती है Access denied - \
इसके अलावा डबल से बचने वाली \\ या डबल दोहरे उद्धरण "" उपयोग करने में मदद नहीं करता है।

तो मेरा सवाल है:
क्या execute_process करते हुए दोहरे उद्धरणों से बचने का एक तरीका है execute_process ताकि वह सही ढंग से अपनी तर्क प्राप्त कर सके?

मैं findstr उपयोग कर सकता findstr , जिसे दोहरे उद्धरण की जरूरत नहीं है; हालांकि यह एक गिनती सुविधा प्रदान नहीं करता है मैं find /v /c "" कॉल करके find सकता हूं, लेकिन फिर से, मुझे दोहरे उद्धरण की आवश्यकता है! और मैं सीएमके के बाहर आउटपुट लाइनों को गिनना चाहूंगा, और परिणाम को MY_COUNT चर में प्रत्यक्ष रूप से स्टोर MY_COUNT

नोट: मैं CMake 3.4.1 का उपयोग कर रहा हूँ

समस्या को पुन: उत्पन्न करने के लिए आप निम्न कोड का उपयोग कर सकते हैं, जिसमें cmake -E echo का उपयोग स्ट्रिंग को find लिए और find करने के लिए किया जाता है:

#This works
execute_process(COMMAND ${CMAKE_COMMAND} -E echo hello COMMAND findstr ell OUTPUT_VARIABLE DUMMY)
message (STATUS "0) DUMMY=${DUMMY}")

#All of the following don't work
set(MyCommand "find \"ell\" /c")
execute_process(COMMAND ${CMAKE_COMMAND} -E echo hello COMMAND "${MyCommand}" OUTPUT_VARIABLE DUMMY)
message (STATUS MyCommand=${MyCommand})
message (STATUS "1) DUMMY=${DUMMY}")

execute_process(COMMAND ${CMAKE_COMMAND} -E echo hello COMMAND ${MyCommand} OUTPUT_VARIABLE DUMMY)
message (STATUS "2) DUMMY=${DUMMY}")

execute_process(COMMAND ${CMAKE_COMMAND} -E echo hello COMMAND MyCommand OUTPUT_VARIABLE DUMMY)
message (STATUS "3) DUMMY=${DUMMY}")

execute_process(COMMAND ${CMAKE_COMMAND} -E echo hello COMMAND "find \"ell\" /c" OUTPUT_VARIABLE DUMMY)
message (STATUS "4) DUMMY=${DUMMY}")

कौन से आउटपुट:

0) DUMMY=hello

MyCommand=find "ell" /c
1) DUMMY=
2) DUMMY=
3) DUMMY=
4) DUMMY=

मैंने भी कोशिश की

set(MyArgument "\"ell\" /c")
message (STATUS MyArgument=${MyArgument})
execute_process(COMMAND ${CMAKE_COMMAND} -E echo hello COMMAND find "${MyArgument}" OUTPUT_VARIABLE DUMMY)
message (STATUS "1) DUMMY=${DUMMY}")

execute_process(COMMAND ${CMAKE_COMMAND} -E echo hello COMMAND find ${MyArgument} OUTPUT_VARIABLE DUMMY)
message (STATUS "2) DUMMY=${DUMMY}")

set(MyArgument "\"ell\"")
message (STATUS MyArgument=${MyArgument})
execute_process(COMMAND ${CMAKE_COMMAND} -E echo hello COMMAND find "${MyArgument}" /c OUTPUT_VARIABLE DUMMY)
message (STATUS "1) DUMMY=${DUMMY}")

execute_process(COMMAND ${CMAKE_COMMAND} -E echo hello COMMAND find ${MyArgument} /c OUTPUT_VARIABLE DUMMY)
message (STATUS "2) DUMMY=${DUMMY}")

कौन से आउटपुट:

MyArgument="ell" /c
File not found - \ELL\

1) DUMMY=
File not found - \ELL\

2) DUMMY=
MyArgument="ell"
Access denied - \

1) DUMMY=
Access denied - \

2) DUMMY=
CMake Error at CMakeRules.cmake:404 (execute_process):
  execute_process given COMMAND argument with no value.
Call Stack (most recent call first):
  CMakeLists.txt:24 (include)

समस्या तब भी बनी रहती है जब कोई भी /c विकल्प हटा दें

इस:

execute_process(COMMAND ${CMAKE_COMMAND} -E echo hello COMMAND find \"ell\" OUTPUT_VARIABLE DUMMY)
message (STATUS "DUMMY=${DUMMY}")

यह आउटपुट करता है:

Access denied - \

DUMMY=

कमांड लाइन को प्रभावी ढंग से पारित करने के लिए कौन सी तार को प्राप्त करने के लिए Tsyvarev सुझाव के बाद, यह:

execute_process(COMMAND cmd /c echo \"ell\")
execute_process(COMMAND cmd /c echo "ell")
execute_process(COMMAND cmd /c echo ""ell"")

यह आउटपुट करता है:

\"ell\"

ell

"" ell\"\"

तीसरे आदेश के लिए एक चेतावनी के साथ:

Argument not separated from preceding token by whitespace.
This warning is for project developers.  Use -Wno-dev to suppress it.




findstr