validar significa recibir que parametros how argumentos and c bash quotes argv

significa - Extraño comportamiento de argv al pasar cadena que contiene "!!!!"



recibir parametros en c (3)

He escrito un pequeño programa que toma algunos parámetros de entrada de *argv[] y los imprime. En casi todos los casos de uso mi código funciona perfectamente bien. Solo aparece un problema cuando uso más de un signo de exclamación al final de la cadena que quiero pasar como argumento ...

Esto funciona:

./program -m "Hello, world!"

Esto no funciona:

./program -m "Hello, world!!!!"

^^ Si hago esto, la salida del programa es el doble de esa cadena o el comando que ingresé antes de ./program.

Sin embargo, lo que absolutamente no entiendo: Lo siguiente, curiosamente, SÍ funciona:

./program -m ''Hello, world!!!!''

^^ La salida es exactamente ...

Hello, world!!!!

... tan deseado.

Entonces, mis preguntas son:

  • ¿Por qué ocurre este extraño comportamiento cuando se usan múltiples signos de exclamación en una cadena?
  • Que yo sepa, en C usas "" para cadenas y '''' para caracteres individuales. Entonces, ¿por qué obtengo el resultado deseado cuando uso '''' , pero no cuando uso "" como debería (a mi entender)?
  • ¿Hay un error en mi código o qué debo cambiar para poder ingresar cualquier cadena (sin importar si, qué y cuántos signos de puntuación se usan) y obtener exactamente esa cadena impresa?

Las partes relevantes de mi código:

// this is a simplified example that, in essence, does the same // as my (significantly longer) code int main(int argc, char* argv[]) { char *msg = (char *)calloc(1024, sizeof(char)); printf("%s", strcat(msg, argv[2])); // argv[1] is "-m" free(msg); }

Ya intenté copiar el contenido de argv[2] en un búfer char* primero y anexarle un ''/0'' , que no cambió nada.


Además de las respuestas proporcionadas, debe recordar que echo es su amigo shell. Si prefieres el comando con "echo", verás qué shell está enviando realmente a tu script.

echo ./program -m "Hello, world!!!!"

Esto le habría mostrado cierta extrañeza y podría haber ayudado a orientarlo en la dirección correcta.


El shell expande en cadenas de comillas dobles. Y si lees la página del manual de Bash (suponiendo que usas Bash, que es el valor predeterminado en la mayoría de las distribuciones de Linux), entonces, si miras la sección Expansión del Historial, ¡verás eso !! medio

Consulte el comando anterior.

Entonces !!!! en su cadena de comillas dobles se expandirá al comando anterior, dos veces.

Dicha expansión no está hecha para cadenas de comillas simples.

Entonces, el problema no está dentro de su programa, se debe al entorno (shell) que llama a su programa.


Esto no está relacionado con tu código, sino con el shell que lo inicia.

En la mayoría de las conchas, !! es la abreviatura de la última orden que se ejecutó. Cuando usas comillas dobles, el shell permite la expansión del historial (junto con la sustitución de variables, etc.) dentro de la cadena, ¡así que cuando lo pones !! dentro de una cadena de comillas dobles, sustituye la última ejecución de comando.

Lo que esto significa para su programa es que todo esto sucede antes de que se ejecute su programa, por lo que no hay mucho que el programa pueda hacer, excepto verificar si la cadena que se pasa es válida.

Por el contrario, cuando utiliza comillas simples, el shell no realiza ninguna sustitución y la cadena se pasa al programa sin modificaciones.

Por lo tanto, debe usar comillas simples para pasar esta cadena. Sus usuarios necesitarían saber esto si no quieren que ocurra ninguna sustitución. La alternativa es crear un script de shell contenedor que le solicite al usuario que pase la cadena, luego el script posteriormente llamará a su programa con los argumentos apropiados.