2013-04-16 15 views
0

J'ai cette ouverture:tcl semble misshandle espaces dans les paramètres

set r [catch {open "|[concat $config(cmd,sh) [list $cmd 2>@1]]" r} fid] 

$config(cmd,sh) est cmd /c et je suis en train de passer un nom de fichier (et peut-être une commande comme écho) dans cmd $. S'il n'y a pas d'espace dans le nom du fichier, à savoir:
cmd est echo /filename
tout va bien. Avec un espace, c'est-à-dire
cmd est echo "/file name" ce qui semble être passé est:
\"file name\".
Lorsque j'essaie ceci sur Linux, j'obtiens "file name" (pas d'antislashs). J'ai essayé de remplacer les espaces dans le nom de fichier par "\ ", mais ensuite la cible obtient deux noms de fichiers, c'est-à-dire que l'espace est utilisé pour diviser le nom de fichier.

Je commence à penser que j'ai trouvé un bug dans le port de Windows de Tcl ...

+0

Voulez-vous dire que cela fonctionne bien sur les systèmes * nix? Je n'ai jamais compris comment citer correctement les paramètres de la ligne de commande sous Windows. – pynexj

+0

Les règles de cotation sous Windows sont obscures et dépendent strictement du runtime C utilisé par l'application cible. C'était terrible, mais maintenant presque tout le monde utilise MSVCRT pour que vous puissiez faire un travail à moitié raisonnable. La couche de liaison de plate-forme Tcl gère la plus grande partie de ceci pour vous, et l'obtient bien dans la plupart des cas: les exceptions principales sont lors de l'appel des builtins CMD, car ils n'utilisent pas le runtime normal. (Pourquoi? Pourquoi?) –

Répondre

3

Ugh, qui semble alambiqué! Pour passer ce genre de chose dans le code de création de pipe, vous devez utiliser exactement la recette:

set r [catch {open |[list {*}$config(cmd,sh) $cmd 2>@1] r} fid] 

C'est, toujours utiliser le formulaire avec |[list ...] lors de la construction des tuyaux que la documentation indique que est ce que le tuyau d'ouverture cherche des. (Ceci est la seule commande comme celle en Tcl.) Et bien sûr, en utilisant la (8.5+) {*} syntaxe est beaucoup plus simple dans ce cas aussi, car il est plus évidemment faire la bonne chose.

+0

Pouvez-vous donner une référence pour la syntaxe {*}? Config (cmd, sh) est "cmd/c" que "list" fait en un mot, essayant ainsi d'exécuter "cmd/c" au lieu de "cmd" avec un paramètre de "/ c", sauf si {*} corrige ce. –

+0

OK, la [liste {*} construit une liste qui fonctionne, mais les espaces dans un paramètre sortent toujours avec le "au lieu du simple". Il semble plus agréable :) –

+2

Hmm, l'automatisation de l'accès à CMD.EXE est l'un des sujets les plus délicats. Le problème est que les builtins CMD.EXE utilisent des règles de guillemets _different_ pour presque toutes les autres commandes sur Windows (un héritage de l'étrangeté dans COMMAND.COM, qui était due à son écriture en assembleur) avec des trucs "intelligents" pour essayer pour déterminer ce que l'utilisateur voulait faire - plutôt que d'utiliser une exécution C cohérente pour l'analyse). Dans certains cas, écrire ce que vous voulez dans un fichier séquentiel et l'exécuter est la seule façon de rester sain d'esprit ... –

Questions connexes