Utilisation du chemin avec des espaces dans le script Shell

J’utilise un script shell pour appeler un programme Java. Lorsque j’appelle passer un programme Java, je passe -Dargument qui a un chemin vers un répertoire. Cet argument -D est lu à partir d’un fichier. Maintenant, je suis confronté à un problème lorsque ce chemin contient des espaces. J’ai essayé avec citation et aussi avec des citations échappant mais les deux fonctionnent bien.

Voici mon code de script shell, test.sh

D_ARG=`(tr '\r\n' ' ' < argument.dat) \#executing java code by passing above argument java ${D_ARG} TestProgram 

Voici mon fichier d’argument, argument.dat

  -Dargument1="/Path /To A/File" 

Lorsque je règle l’écho sur set -x, le shell le convertit en

  '-Dargument1="/Path' '/To' 'A/File"' 

Où il ajoute des guillemets simples quand il rencontre des espaces et que j’obtiens la classe “/ To” non trouvée. Comment résoudre ce problème. Toute suggestion ou aide sera vraiment appréciable.

Essaye ça:

 ARGS= # Do nothing if there are no spaces; if there are spaces, surround with quotes for arg in $(perl -pe '/ / or next; s/^/"/; s/$/"/' argument.dat); do ARGS="$ARGS $arg"; done java $ARGS TestProgram 

Cela a pour effet que chaque fois qu’une ligne contient un espace, elle sera entourée de guillemets, de sorte que -Da=bc sera transformé en "-Da=bc" .

Notez que "-Da=bc" est ssortingctement équivalent à -Da="bc" , ou même à des formes plus bizarres:

  • '-Da='b\ c ;
  • -D"a=b "c ;
  • etc

La seule chose qui compte est que, quels que soient les caractères, les séparateurs de champs en entrée sont échappés. Oui, c’est légal:

 alias l"l=ls"\ -l 

Vous pouvez éventuellement échapper les espaces dans “/ Path / To A / File”. Ce n’est cependant pas une bonne solution, car plusieurs fois, nous pouvons formuler une commande comme

 system(argv[1]);/* Example is C specific; but you understand the loop-hole imparted by single escaping. You may require multilevel escaping, based on your implementation. OR We may have to escape the ssortingng, every time it is dereferenced. */ 

De meilleures options sur les systèmes Linux sont de créer un lien symbolique.

 ln -s "/Path /To A/File" /tmp/file 

& puis dans le fichier d’argument, utilisez -Dargument1="/tmp/file"
Utilisez cette approche s’il n’y a qu’un seul fichier "/Path /To A/File" en question.


Une autre approche consiste à utiliser mount --bind

 mkdir /tmp/myfiles && mount --bind "/Path /To A" /tmp/myfiles 

& puis dans le fichier d’argument, utilisez -Dargument1="/tmp/myfiles/File"
Cette approche monterait "/Path /To A" dans /tmp/myfiles . Toute la structure des fichiers et répertoires sera conservée.

Le script a fonctionné lorsqu’il est utilisé avec la commande eval, qui conserve les guillemets et ajoute les guillemets simples supplémentaires.

  D_ARG=`(tr '\r\n' ' ' < argument.dat) \#executing java code by passing above argument eval java ${D_ARG} TestProgram