2017-10-18 5 views
0

Ce script est incomplet puisque je veux faire des tests d'erreur plus tard, mais l'idée est que ARG est un script et PARAM2 est un répertoire, et ARG doit marquer tous les fichiers dans PARAM2. Comment ferais-je cela de telle manière que bash sache que le premier argument doit être un script et que l'argument 2 est un répertoire?Scripts Passing comme arguments Bash

ARG=$1 
ARG2=$2 
CHECK=0 
aCount=0 
bCount=0 
cCount=0 
dCount=0 
fCount=0 

if [ $CHECK -e 0 ]; then 
    for files in $ARG2; do 
     if [ sh $1 $2 -eq A]; then 
      aCount=$((aCount+1)) 
     elif [ sh $1 $2 -eq B]; 
      bCount=$((bCount+1)) 
     elif [ sh $1 $2 -eq C]; 
      cCount=$((cCount+1)) 
     elif [ sh $1 $2 -eq D ]; 
      dCount=$((dCount+1)) 
     else; 
      fCount=$((fCount+1)) 
     fi 
    done 
fi 

echo A: $aCount 
echo B: $bCount  
echo C: $cCount   
echo D: $dCount 
echo F: $fCount 

Répondre

4

Il existe une variété d'erreurs que vous pourriez attraper en exécutant votre script par shellcheck.net.

Corrections:

  • Pour boucler sur les fichiers dans un répertoire, écrivez for file in dir/* pas for file in dir. Ces derniers boucles juste une fois avec $file ensemble à la chaîne "dir", plutôt que itérer sur le contenu du répertoire dir/.

  • [ sh $1 $2 -eq A] est un fouillis de constructions en coquille. Vous voulez capturer la sortie du script, vous avez donc besoin $(...). Vous faites une vérification de la chaîne, vous devez donc utiliser == pas -eq. Correction les rendements:

    [ $(sh $1 $2) == A ] 
    
  • Je devine $2 devrait être $files, cependant. La variable de boucle, oui?

    [ $(sh $1 $files) == A ] 
    
  • Il y a d'autres erreurs diverses, telles que manque then s et pas toujours avoir un espace avant ].

Améliorations:

  • Vous devez citer tout correctement pour éviter la séparation de mots par inadvertance et à l'expansion de glob.

    [ "$(sh "$1" "$files")" == A ] 
    
  • Remplaçons $1 avec $script et $files avec singulier $file.

    [ "$(sh "$script" "$file")" == A ] 
    
  • Si le script a une ligne de tralala à proprement parler comme #!/bin/bash en haut alors il n'y a pas besoin d'invoquer explicitement sh.

    [ "$("$script" "$file")" == A ] 
    
  • Tout est génial. Maintenant vous avez quelque chose comme ceci:

    if [ "$("$script" "$file")" == A ]; then 
        aCount=$((aCount+1)) 
    elif [ "$("$script" "$file")" == B ]; then 
        bCount=$((bCount+1)) 
    elif [ "$("$script" "$file")" == C ]; then 
        cCount=$((cCount+1)) 
    elif [ "$("$script" "$file")" == D ]; then 
        dCount=$((dCount+1)) 
    else 
        fCount=$((fCount+1)) 
    fi 
    

    Horriblement répétitif, non? Essayons plutôt une instruction case.

    case "$("$script" "$file")" in 
        A) aCount=$((aCount+1));; 
        B) bCount=$((bCount+1));; 
        C) cCount=$((cCount+1));; 
        D) dCount=$((dCount+1));; 
        *) fCount=$((fCount+1));; 
    esac 
    
  • Cette déclaration de cas est encore assez complexe. Brisons-le pour le rendre plus facile à analyser.

    grade=$("$script" "$file") 
    
    case $grade in 
        ... 
    esac 
    
  • Les noms de variables doivent être en minuscules. Les noms UPPERCASE sont réservés au shell, il est donc préférable de ne pas les utiliser. Remplacez COUNT par count.

  • Renommons ARG et ARG2-script et dir, respectivement. Des noms significatifs rendent tout plus facile à lire.

  • var=$((var+1)) peut être simplifié à ((var += 1)) ou ((var++)).

Résultat final:

script=$1 
dir=$2 

check=0 
aCount=0 
bCount=0 
cCount=0 
dCount=0 
fCount=0 

if ((check == 0)); then 
    for file in "$dir"/*; do 
     grade=$("$script" "$file") 

     case $grade in 
      A) ((aCount++));; 
      B) ((bCount++));; 
      C) ((cCount++));; 
      D) ((dCount++));; 
      *) ((fCount++));; 
     esac 
    done 
fi 

echo "A: $aCount" 
echo "B: $bCount" 
echo "C: $cCount" 
echo "D: $dCount" 
echo "F: $fCount" 
+0

Nevermind, je l'ai compris. Merci beaucoup :) – DrJessop

2

@John Kugelman a fait un grand travail ci-dessus. Pour une autre prise -

declare -A count     # count is an array 
for file in "$dir"/*    # skipping assignments, and $check 
do grade=$("$script" "$file")  # grab the output as $grade 
    case $grade in     # look up its value 
    [A-D]) ((count[$grade]++));; # use as-is for a-d 
     *) ((count['F']++ ));; # throw everything else in f 
    esac 
done 

for g in A B C D F     # then for a-f (known values) 
do echo "$g: "${count[$g]}   # pull the counts 
done 
+0

Un tableau est une excellente idée. J'ai manqué d'espace dans ma réponse. ;) –

+1

Vous aurez besoin de 'declare -A' pour un tableau associatif. –

+0

I * avait * '-A', et a commencé à tester quelques options, et a fini par ne pas le remettre. Merci, édité/corrigé. –