staging.inyokaproject.org

Feedback zu meinem Script

Status: Ungelöst | Ubuntu-Version: Xubuntu 20.04 (Focal Fossa)
Antworten |

Paddy_123

Anmeldungsdatum:
19. Juli 2020

Beiträge: 27

Hallo liebes Forum, ich versuche mich gerade in scripting einzuarbeiten und hätte gerne Feedback zu meinem "ersten" kleinen Script

Mein Script ist eine einfache Suche nach File oder Directory mit kleinem Menü das mir entweder die File anzeigt oder direkt ins Verzeichnis wechselt. Es beschränkt sich zunächst nur aufs Homeverzeichnis und ich starte es mit: source ./script

Mir geht es vor allem um Feedback hinsichtlich der Übersichtlichkeit, ist es verständlich für andere? Kann ich es effizienter / besser gestalten / kürzer:

Vielen Dank, hier mein Script

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#!usr/bin/zsh
echo "Was suchst du?"
echo "1         File"
echo "2                 Directory"
echo "3         Abbrechen"
echo "Gib bitte eine Zahl ein :) "
read n

if [[ $n -eq 1 ]]
then
          echo "Welche file suchst du?"
          read f                                                 #Eingabe welche File gesucht wird
          echo "Möchtest du ins Verzeichnis wechseln?"
          echo "1        JA"
          echo "2        NEIN"
          read antwort                                           #ins Directory wechseln ja/nein?
          f1=$( find ~/ -type f -iname $f )
          f2=$( dirname $f1 )
          if [[ $antwort -eq 1  ]] then
                  cd $f2                                         #wechselt ins Diretory
          elif then
                  echo $f1                                       #gibt File aus
          fi
elif [[ $n -eq 2  ]] then
         echo "Welches Directory suchst du?"
         read d
         echo "Möchtest du ins Directory wechseln?"
         echo "1         Ja"
         echo "2         NEIN"
         read antwort
         d1=$( find ~/ -type d -iname $d )
         if [[ $antwort -eq 1  ]] then
                 cd $d1
         elif then
                 echo $d1
         fi
elif [[ $n -eq 3 ]] then
         echo "Programm abgebochen, einen schönen Tag noch."
else
         echo "Fehler in der Eingabe"
fi

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

Du hast das grundsätzliche Problem, dass ein cd in Deinem Skript keine Auswirkungen auf die aufrufende Shell hat, zu der Du ja zurückkehrst sobald das Skript beendet ist. So etwas bekommt man elegant nur mit einer Shell-Funktion hin, die in der ~/.bashrc oder ~/.bash_aliases definiert wird.

Ganz allgemein finde ich "Datei / Ordner Suchen" und "In Verzeichnis wechseln" verschieden genug, dass ich sie nicht in einem Skript abhandeln würde. Dann kannst Du nämlich auch das unten genannte Problem mit mehreren gefundenen Dateien leichter handhaben (z.B. indem Du nach der Ausgabe des ersten Treffers find beenden lässt).

Du hast da einiges an redundantem Code in den beiden Zweigen für "Datei" und "Ordner". Das könnte man elegant zusammenfassen, indem man z.B. den gesuchten Dateityp in einer Variable ablegt, die dann hinter find -type verwendet wird.

Dann hast Du ein Problem, wenn mehrere Dateien des angegebenen Namens gefunden werden. Dann sehen $f2 und $f2 (nicht sehr sprechende Namen übrigens) nicht so aus, wie Du vielleicht möchtest. Insbesondere wird dann der cd mehr als ein Argument sehen und sich beschweren.

Ich persönlich bin kein großer Fan von interaktiven Skripten. Man hat ja schon die interaktive Shell und kann dann da auch Parameter an ein Skript übergeben.

Paddy_123

(Themenstarter)

Anmeldungsdatum:
19. Juli 2020

Beiträge: 27

Ich hab es nochmal durchgetestet und es war ziemlich unbefriedigend. Hat nur "unicative Dateien" gefunden und ins Verzeichnis gewechselt.

Bei Mehrfachausgabe wusstes es nicht nicht in welches Verzeichnis gewechselt werden soll. Ich habe versucht mit

find ~/ -type f -iname $1 | nl | grep $2

zu pipen. Ich könnte dann auch z.B NR 2 auswählen und ausgeben, allerdings weiß ich nicht wie ich die 2 wieder entferne um sie ins cd-Command zu schmeißen.

Weiter habe ich noch mit | wc -l eine weitere If-Abfrage eingebaut. Wenn ich mehrere Treffer habe kommt eine weitere Abfrage.

Hier der erweiterte Code; Das ganze Ding sollte man doch mit functions wesentlich übersichtlicher hinebkommen oder?

Vielen Dank Pad

// Ach ja so richtig getestet hab ich die Version noch nicht, hab kein Nerv mehr heute dafür ☺

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#!/usr/bin/zsh
#Suchprogramm für Files oder Directories mit der Option in diese zu wechseln.
#
#Intro Menu
echo "Was suchst du?"
echo "1         File"
echo "2                 Directory"
echo "3         Abbrechen"
echo "Gib bitte eine Zahl ein :) "
read n

#Filesuche
if [[ $n -eq 1 ]]
then
         echo "Welche file suchst du?"
         read f                                                 #Eingabe welche File gesucht wird
         echo "Möchtest du ins Verzeichnis wechseln?"
         echo "1        JA"
         echo "2        NEIN"
         read antwort                                           #ins Directory wechseln ja/nein?
         #Var definitionen
         f1=$( find ~/ -type f -iname $f )
         f2=$( dirname $f3 )
         f4=$( dirname $f )
         if [[ $antwort -eq 1  ]] then
#WC filtert die Anzahl der Ergebnisse heraus
                 wc=$( find ~/ -type f -iname $f | wc -l )
#Wenn mehrere Suchtreffer dann wird mit grep eingeschränkt.
                 if [[ wc -gt 1  ]] then
                        echo $f1
                        echo "In welchem Ordner soll ich suchen? Bitte etwas unicatives"        #falls es mehrere Optionen gibt
                        read x
                        f3=$( find ~/ -type f -iname $f | grep $x  )
                        cd $f2
#Wenn nur ein Treffer kann direkt ins Verzeichnis gewechselt werden
                elif cd $f4
                fi
#Oder Ordnerwechsel ist nicht gewünscht und Suchergebnis wird asugegeben
         elif then
                 echo $f1                                       #gibt File aus
        fi
# Suche nach Directories
elif [[ $n -eq 2  ]] then
        echo "Welches Directory suchst du?"
        read d
        echo "Möchtest du ins Directory wechseln?"
        echo "1         Ja"
        echo "2         NEIN"
        read antwort
        d1=$( find ~/ -type d -iname $d )
        if [[ $antwort -eq 1  ]] then
#WC Suche wie bei Files
                 wc=$( find ~/ -type d -iname $d | wc -l )
                 if [[ $wc -gt 1  ]] then
                         echo $d1
                         echo "In welchem Ordner soll ich suchen? Gib etwas unicatives ein"     #falls es mehrere Optionen gibt
                         read x
                         d2=$( find ~/ -type d -iname $d | grep $x  )
                         cd $d2
                 elif
                         cd $d1
                 fi
#Wenn kein Verzeichniswechsel gewünscht dann Ausgabe
        elif then
                echo $d1
        fi
#Option 3 // Programmabbruch oder falsche Eingabe
elif [[ $n -eq 3 ]] then
        echo "Programm abgebochen, einen schönen Tag noch."
else
        echo "Fehler in der Eingabe"
fi                          

Paddy_123

(Themenstarter)

Anmeldungsdatum:
19. Juli 2020

Beiträge: 27

rklm schrieb:

Du hast das grundsätzliche Problem, dass ein cd in Deinem Skript keine Auswirkungen auf die aufrufende Shell hat, zu der Du ja zurückkehrst sobald das Skript beendet ist. So etwas bekommt man elegant nur mit einer Shell-Funktion hin, die in der ~/.bashrc oder ~/.bash_aliases definiert wird.

Wenn ich es im Terminal mit "source ./script" öffne wird es ausgeführt ohne Probleme auch der cd-Befehl funktioniert. Ohne "source" ist es richtig

Ganz allgemein finde ich "Datei / Ordner Suchen" und "In Verzeichnis wechseln" verschieden genug, dass ich sie nicht in einem Skript abhandeln würde. Dann kannst Du nämlich auch das unten genannte Problem mit mehreren gefundenen Dateien leichter handhaben (z.B. indem Du nach der Ausgabe des ersten Treffers find beenden lässt).

Ob das Programm notwendig oder sinnvoll ist bezweifel ich ebenfalls ☺. Ein Menu macht es träge. Mir ging es aber mehr darum mit ifs und variablen zu arbeiten. Mit dem find-Befehl bekomm ich ein Ergebnis und sehe wie weit ich noch entfern bin ☺

Du hast da einiges an redundantem Code in den beiden Zweigen für "Datei" und "Ordner". Das könnte man elegant zusammenfassen, indem man z.B. den gesuchten Dateityp in einer Variable ablegt, die dann hinter find -type verwendet wird.

Wie meinst du das mit zusammenfassen? Die Frage ist ob der Typ überhaupt notwendig ist ... mit iname kann ich ja grundsätzlich nach beidem suchen. Aber auch hier ging es mir mehr ums Menu und verschachtelte ifs und oder andere Vorschläge

Dann hast Du ein Problem, wenn mehrere Dateien des angegebenen Namens gefunden werden. Dann sehen $f2 und $f2 (nicht sehr sprechende Namen übrigens) nicht so aus, wie Du vielleicht möchtest. Insbesondere wird dann der cd mehr als ein Argument sehen und sich beschweren.

Das habe ich auch festgestellt und noch was dran gehängt um bei Mehrfachausgabe nochmals zu diffenzieren. Das $f nicht ansprechend ist habe ich im selben Zug gemerkt ... als ich bei den wenigen Zeilen schon leicht durcheinander gekommen bin.

Danke fürs Feedback und die Zeit 😉

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

Paddy_123 schrieb:

// Ach ja so richtig getestet hab ich die Version noch nicht, hab kein Nerv mehr heute dafür ☺

In Zeile 23 ist f3 nicht definiert.

So könnte man das auch machen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
d() {
  case "$1" in
  file) type=f;;
  dir) type=d;;
  *) echo "ERROR: command is 'file' or 'dir'"; return 1;;
  esac

  case "$2" in
  cd) found="$(find -type $type -iname "$3" -print -quit)"
      if [ -d "$found" ]; then
        cd "$found"
      else
        cd "$(dirname "$found")"
      fi;;
  show) find -type $type -iname "$3";;
  *) echo "ERROR: operation is either 'cd' or 'show'"; return 2;;
  esac
}

Paddy_123

(Themenstarter)

Anmeldungsdatum:
19. Juli 2020

Beiträge: 27

In Zeile 23 ist f3 nicht definiert.

Ich hab es in Zeile 33 definiert. Führt das zu einem Fehler?

Deine Version sieht deutlich angenehmer aus und leuchte mir denke ich so weit auch ein (ich schau es mir morgen mal genauer an). Nur eine Sache versteh ich nicht.

      else
        cd "$(dirname "$found")"
      fi;;

Warum hast du hier 2 ";;" gesetzt? Reicht "fi" nicht aus? Oder hat das was mit case zu tun?

Danke dir für deine Mühe.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

Paddy_123 schrieb:

In Zeile 23 ist f3 nicht definiert.

Ich hab es in Zeile 33 definiert. Führt das zu einem Fehler?

Klar:

1
2
3
4
5
6
$ dirname $leer
dirname: missing operand
Try 'dirname --help' for more information.
$ dirname
dirname: missing operand
Try 'dirname --help' for more information.

Deine Version sieht deutlich angenehmer aus und leuchte mir denke ich so weit auch ein (ich schau es mir morgen mal genauer an). Nur eine Sache versteh ich nicht.

      else
        cd "$(dirname "$found")"
      fi;;

Warum hast du hier 2 ";;" gesetzt? Reicht "fi" nicht aus? Oder hat das was mit case zu tun?

Letzteres. Die zwei Semikolons beenden einen Fall vom case.

Mir fällt noch auf, ich habe vergessen die Fehlermeldungen nach Stderr umzuleiten. Also z.B. in Zeile 5 sollte es dann so aussehen:

1
  *) echo "ERROR: command is 'file' or 'dir'" >&2; return 1;;

Danke dir für deine Mühe.

Bitte!

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17630

Die Bash kennt den praktischen select-Befehl:

1
2
3
4
select datei in $(find . -type f -name ....) 
do 
  # mach was mit $datei
done

Hat die zsh sowas nicht?

Paddy_123

(Themenstarter)

Anmeldungsdatum:
19. Juli 2020

Beiträge: 27

user_unknown schrieb:

Die Bash kennt den praktischen select-Befehl:

1
2
3
4
select datei in $(find . -type f -name ....) 
do 
  # mach was mit $datei
done

Hat die zsh sowas nicht?

Doch hat sie, kannte ich aber bisher noch nicht. Werd ich auch mal mit rumspielen.

Ich hab das ganze Teil jetzt nochmal mit case ausporbiert, es ist kürzer läuft aber noch nicht ..

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/usr/bin/zsh
#Programm um File oder Directory zu suchen, auszugeben oder ins Directory zu wechseln.
#
#Abfrage f or d
echo "Was suchst du?"
echo "1=File"
echo "2=Directory"
read fileordirectory

#Abfrage Suche
echo "Gib deine Suche ein!"
read suche
#Abfrage show of change
echo "Möchtest du deine Suche anzeigen oder wechseln?"
echo "1=wechseln"
echo "2=anzeigen"
read showorchange

#File or Dir case
case $fileordirectory in
	1) type=f;;
	2) type=d;;
	*) echo "Error existiert nicht" >&2; return 1;;
esac

#Suche	
case $showorchange in
	1)morethan1=$(find /home/$(whoami)/ -type $type -iname $suche | wc -l)
		#Wenn mehr als ein Suchergebnis existiert mit wc -l Zeilen zählen
		if [ $morethan1 -gt 1  ]; then
			 find /home/$(whoami)/ -type $type -iname $suche | nl
			 echo "Welches Ergebnis möchtest du?"
			 read x
# head + tail = x
			 let headtail=$morethan1-$x 
			 	if [ $fileordirectory -eq 2  ]; then
					cd $(find /home/$(whoami)/ -type $type -iname $suche | head -n$x | tail -n$headtail) 
				else 
					cd $(dirname $(find /home/$(whoami)/ -type $type -iname $suche | head -n$x | tail -n$headtail)) 
				fi
				
		else [ $morethan1 -eq 1 ]; then
			found1=$(find /home/$(whoami)/ -type $type -iname $suche)
				if [ $fileordirectory -eq 2 ]; then
					cd $found1
				else
					cd $(dirname $found1)
				fi
		fi;;
	2) find /home/$(whoami)/ -type $type -iname $suche;;
	*) echo "Nichts gefunden"; return 2;;
esac

Ich bekomme folgenden Fehler:

1
./casetest.sh:42: parse error near `then'

2 Fragen hierzu: 1. im Fehlerprotokoll zählt er die Kommentare nicht mit. Ich behelfe mir indem ich die Datei mit 'cat "script" | nl ' anzeigen lasse. Ich arbeite mit VIM kann man hier die Kommentare irgendwie ausblenden bzw wie finde ich in VIM Zeile 42 ... was im VIM eigentlich Zeile 44 wäre.

2. Wenn ich bei der Abfrage 1 für File, dann die File und bei "Suchen oder Anzeigen" 2 eingebe. Sollte er doch eigentlich Case 1 "Anzeigen" überspringen/auslassen. Hier zeigt er mir aber auch den Fehler an.

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17630

Ich habe die ZSH nie benutzt, daher eine wüste Spekulation:

1
else [ $morethan1 -eq 1 ]; then

In der Bash müsste das Schlüsselwort elif heißen, wenn danach eine weitere Bedingung kommt. In anderen Sprachen benutzt man einfach ein neues if nach else.

Paddy_123

(Themenstarter)

Anmeldungsdatum:
19. Juli 2020

Beiträge: 27

user_unknown schrieb:

Ich habe die ZSH nie benutzt, daher eine wüste Spekulation:

1
else [ $morethan1 -eq 1 ]; then

In der Bash müsste das Schlüsselwort elif heißen, wenn danach eine weitere Bedingung kommt. In anderen Sprachen benutzt man einfach ein neues if nach else.

Benutzt man nicht immer if / elif / else?

In Zeile 30 mach die IF auf und dann kommt nur else

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
if [ $morethan1 -gt 1  ]; then
			 find /home/$(whoami)/ -type $type -iname $suche | nl
			 echo "Welches Ergebnis möchtest du?"
			 read x
# head + tail = x
			 let headtail=$morethan1-$x 
----------------------------------
		
else [ $morethan1 -eq 1 ]; then
			found1=$(find /home/$(whoami)/ -type $type -iname $suche)
				if [ $fileordirectory -eq 2 ]; then
					cd $found1
				else
					cd $(dirname $found1)
				fi
fi;;

Oder versteh ich da was falsch?

Danke dir

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17630

Ich habe Zeile 40 zitiert, da steht ein

1
else BEDINGUNG ; then ...

Aber üblicherweise folgt einem else keine Bedingung.

1
2
3
4
5
6
if (( 3 > 4 )) 
then 
    echo nanana 
else 
    echo nun ja
fi

Drei ist größer als 4 oder auch nicht.

Eine weitere Bedingung erzwingt in den meisten Sprachen ein verschachteltes, neues if:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
if (( 3 > 4 )) 
then 
    echo nanana 
else 
    if (( 3 == 4 )) 
    then 
        echo kaum besser
    else 
        echo ja
    fi
fi

wobei die Bash das Schlüsselwort **elif** anbietet:

1
2
3
4
5
6
7
8
9
if (( 3 > 4 )) 
then 
    echo nanana 
elif (( 3 == 4 )) 
then 
    echo kaum besser
else 
    echo ja
fi

Was die Zsh macht, weiß ich nicht.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

user_unknown schrieb:

wobei die Bash das Schlüsselwort **elif** anbietet:

Das ist sogar POSIX-Standard.

1
2
3
4
5
6
7
8
9
if (( 3 > 4 )) 
then 
    echo nanana 
elif (( 3 == 4 )) 
then 
    echo kaum besser
else 
    echo ja
fi

Was die Zsh macht, weiß ich nicht.

Das gleiche.

Antworten |