Cela me donne une erreur qui dit trop d'arguments:
if [ $( file -b $i ) == "directory" ]
Mais quand j'ai essayé ça
name=$( file -b $i ) if [ name == "directory" ]
Cela semble fonctionner très bien.
Quelqu'un peut-il expliquer cela ou indiquer dans les documents une explication? Je suis nouveau à bash mais du sharepoint vue d'autres langages de programmation cela n'a aucun sens.
Quelques problèmes:
]
indique la fin des arguments pour [
( test
), et il doit être le dernier argument; vous avez quelques ]
s, ce qui est faux; vous pensiez probablement utiliser:
if [ $( file -b $i ) == "directory" ]
Si vous aviez utilisé ce qui précède, vous obtiendrez bash: [: too many arguments
, parce que la division des mots se ferait sur la sortie de l'extension de variable ( $i
), puis la substitution de command, $()
[
verra plusieurs mots avant =
, conduisant au message d'erreur. Vous devez citer l'extension de variable et la substitution de command:
[ "$(file -b "$1")" == "directory" ]
Comme note de côté, vous devriez utiliser le mot-key bash
[[
, au lieu de [
comme le premier traitera le fractionnement de mots (et l'extension de nom de path) pour vous.
if [ $( file -b $i ) == "directory" ]
Deux questions ici:
Utilisez single =
pour la comparaison de strings. Voir man test
pour une syntaxe correcte (notez que [
dans de nombreux cas, l'implémentation est spécifique à un shell, consultez la man page
votre shell si vous n'avez pas de documentation pour le test
). Si vous avez absolument besoin ==
, utilisez [[
place, ce qui est caractéristique de beaucoup de shells comme Bourne, y compris bash, ksh, zsh. REMARQUE: while ==
existe dans bash depuis la version 2.0 , "= doit être utilisé avec la command de test pour la conformité POSIX." ( page de bash man ).
Mentionnez toutes vos variables comme "$()"
. Spécifiquement d'intérêt est $i
. Les noms de files avec espace vont casser $i
en plusieurs mots en raison de l'expansion des mots du shell.
Exemple:
bash-4.3$ mkdir with\ space bash-4.3$ i="./with space" bash-4.3$ set -x bash-4.3$ [ $( file -b $i ) == "directory" ] && echo "YES" ++ file -b ./with space + '[' cannot open '`./with'\''' '(No' such file or 'directory)' cannot open '`space'\''' '(No' such file or 'directory)' == directory ']' bash: [: too many arguments
name=$( file -b $i ) if [ name == "directory" ]
Problèmes ici:
name
n'est pas développé en variable, c'est juste une string "nom" ici. Vous avez besoin de "$name"
et encore, single =
En outre, il ne peut pas avoir fonctionné, puisque le statut de sortie du test
est renvoyé comme faux (état de sortie 1)
$ name=$(file -b /etc) $ set -x $ [ name == "directory" ] + '[' name '==' directory ']' $ echo $? + echo 1 1
Le testé ci-dessus sur les obus bash
et mksh
.
Il y a beaucoup de problèmes! Prenons cette partie qui "travaille":
name=$( file -b $i ) if [ name == "directory" ]
Cela affecte la sortie de la command file à la variable appelée name
, mais ne l'utilise pas; à la place, il exécute la command [
avec 3 parameters: name
, ==
, et directory
. Accepter ==
est une extension bash.
Si cela a été corrigé pour utiliser $name
plutôt que name
vous obtiendrez à nouveau un problème d' too many arguments
dans de nombreux cas. C'est parce que le file
renvoie plusieurs résultats de mots comme ASCII text
. Donc, après que la command a couru, vous obtenez
if [ ASCII text == directory ]
et maintenant il est évident que la command manque un certain groupement.
if [ "$(file -b -- "$i")" = "directory" ]
est probablement ce que vous voulez: =
plutôt que ==
pour la portabilité, et en citant le résultat de la substitution de commands que vous voulez presque toujours faire .