files - findstr windows examples
CMake: ¿Cómo llamar a execute_process con una comilla doble en el argumento? también conocido como Using find from CMake para contar líneas que coincidan con una cadena (1)
De acuerdo con los desarrolladores de CMake ,
No se puede invocar directamente el hallazgo de Windows mediante cmake desde execute_process
, debido a una limitación de la API de CreateProcess y de la manera no estándar de find
argumentos de análisis.
Sin embargo, se puede llamar indirectamente al crear un script por lotes temporal.
Mi problema de contar las ocurrencias de una cadena desde la salida de un programa en Windows se resuelve de la siguiente manera:
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)
La ventaja de findstr
en el medio es que admite expresiones regulares. find
solo se usa para contar líneas coincidentes .
El @
delante de find
es para evitar que la invocación de comando dentro del script termine en la variable de salida.
Me gustaría llamar al comando find
desde dentro de un execute_process
.
El formato del comando find
es:
find [/v] [/c] [/n] [/i] [/off[line]] "<String>" [[<Drive>:][<Path>]<FileName>[...]]
Entonces, la cadena debe ser doblemente citada. Sin embargo, si en cmake lo hago:
execute_process(COMMAND <firstCommandPipingSomethingToFind>
COMMAND find "<myString>" /c
OUTPUT_VARIABLE MY_COUNT
OUTPUT_STRIP_TRAILING_WHITESPACE)
Aparece un error FIND: Parameter format not correct
.
Si escapo las comillas dobles con /
, obtengo un error Access denied - /
.
También usar dobles escapes //
o dobles comillas dobles ""
no ayuda.
Entonces mi pregunta es:
¿Hay alguna forma de evitar las comillas dobles cuando se llama a execute_process
para que find
reciba correctamente su argumento?
Podría usar findstr
, que no necesita las comillas dobles; sin embargo, no proporciona una función de conteo. Podría usar find
llamando a find /v /c ""
, pero de nuevo, ¡necesito comillas dobles! Y me gustaría contar las líneas de salida fuera de cmake, y almacenar directamente el resultado en MY_COUNT
variable.
Nota: estoy usando CMake 3.4.1
Para reproducir el problema, puede usar el siguiente código, en el cual cmake -E echo
se usa para alimentar una cadena a findstr
y 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}")
Qué salidas:
0) DUMMY=hello
MyCommand=find "ell" /c
1) DUMMY=
2) DUMMY=
3) DUMMY=
4) DUMMY=
También intenté
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}")
Qué salidas:
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)
El problema persiste también si se elimina la opción /c
.
execute_process(COMMAND ${CMAKE_COMMAND} -E echo hello COMMAND find /"ell/" OUTPUT_VARIABLE DUMMY)
message (STATUS "DUMMY=${DUMMY}")
salidas esto:
Access denied - /
DUMMY=
Siguiendo la sugerencia de Tsyvarev de recuperar qué cadena se pasa efectivamente a la línea de comando, esto:
execute_process(COMMAND cmd /c echo /"ell/")
execute_process(COMMAND cmd /c echo "ell")
execute_process(COMMAND cmd /c echo ""ell"")
salidas esto:
/"ell/"
ell
"" ell/"/"
Con una advertencia para el tercer comando:
Argument not separated from preceding token by whitespace.
This warning is for project developers. Use -Wno-dev to suppress it.