• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

[gelöst] seltsames Konsole-Ausgabe Problem

OsunSeyi

Hacker
Hi,
frage aus Interesse:
Code:
#!/bin/sh

	d0=$HOME'/Desktop/usr-bin'
	d1=$HOME'/Desktop/usr-bin-sl'

	        number_lines=`wc -l $d0 | sed 's|[^[:digit:]]||g'`   

        n=0

        while [ $n -le $number_lines ] ; do
                n=`expr $n + 1`

                item=`sed -n "$n p"  $d0`
		test=`grep   "$item" $d1`

		if [ -z "$test" ] ; then

		echo $item

		fi
        done

Zunächst: so schaut also ein typisches Tom-mäßiges Script aus...Tips also erwünscht.
Es soll nach Einträgen in Datei $d0 suchen, die nicht auch in $d1 vorkommen.
Sagt nicht, das ginge auch mit 'diff'....
Was aber total seltsam ist, daß sich das Script brav aufrufen lässt und das gewünschte Ergebniss ausspuckt,
leite ich die Ausgabe in eine Datei um, klappt's aber nicht!

Code:
compare
...klappt
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compare > Ausgabedatei
..bleibt irgendwo auf der Hälfte einfach hängen, an dem Eintrag bei dem's hakelt selbst ist nichts
zu finden. Keine Sonderzeichen oder so.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compare | tee Ausgabedatei
...klappt
Wie kann das sein?
 
A

Anonymous

Gast
Das script ist schlichtweg eine Katastrophe
Code:
number_lines=`wc -l $d0 | sed 's|[^[:digit:]]||g'`
ist viel zu umständlich und falsch, wenn da im Dateinamen Ziffern enthalten sind, dann kommen zufällige viel zu große Zahlen heraus.
besser
Code:
wc -l $d0 | cut -d " " -f1
oder was weiß ich, irgend was Einfaches
Code:
awk 'END{print NR}' $d0
oder wenn es schon wc und sed sein soll, dann so hier ist besser
Code:
wc -l $d0 | sed 's/ .*$//'


Code:
item=`sed -n "$n p"  $d0`
funktioniert hier zwar, ist aber außerst riskant. siehe hier wie man's richtig macht

Code:
test=`grep   "$item" $d1`

      if [ -z "$test" ] ; 

      echo $item

      fi
Firle-Fanz :schockiert: :zensur:
was passiert denn hier wenn die Zeile 2 Mal gefunden wird? Warum wertest du nicht gleich den Rückgabewert von grep aus, anstatt das dann nochmal in eine Variabe zu schreiben und dann diese zu testen?
Besser so hier
Code:
if grep -q "$item" $d1 ; then ......
Wenn du allerdings hier mit Grep suchen willst, dann musst du hier auch noch zusätzlich strikt dafür sorgen, das nur ganze Zeilen gefunden werden die dem Suchstring entsprechen, sonst kommt irgendwas zufälliges heraus, je nachdem was der Inhalt der Dateien ist, aber nicht das was du willst. Hast du denn auch mal probiert ob da auch alle Sonderzeichen in den Dateien gehen? und ob diese auch wirklich dann noch so bei Grepaufruf ankommen und zwar genauso wie sie auch in den Dateien stehen?

n=0

while [ $n -le $number_lines ] ; do
n=`expr $n + 1`
:schockiert: viel zu komplizierter und fehleranfällig, einfache Zahlschleifen darf man in Linux auch in der bash mit for machen solange es Integerwerte sind.

So etwa hier
Code:
for n in `seq 0 $number_lines `
do 
# echo $n
........

Soll ich weiter das Script in der Luft zerreißen ;) ?????? Dann als erstes mal das gesamte Erscheinungsbild. Wetten, nächste Woche siehst du selbst nicht mehr was du da zusammengeschustert hast. :D
Wenn so ein :zensur: Script Nebenwirkungen zeigt, ist das nur völlig normal. Bei mir bringt es übrigens irgendwelche nicht nachzuvollziehenden Ergebnisse, aber nicht das was du beschreibst, was dabei herauskommen soll.

robi
 
OP
OsunSeyi

OsunSeyi

Hacker
Vielen Dank für die Antwort.
Bei einem listing von /usr/bin wäre es in der Tat nicht nötig, zeilenweise auszulesen.
Code:
number_lines=`wc -l $d0 | sed 's|[^[:digit:]]||g'`
Ist grottenfasch... :eek:ps:

Trotzdem ist der Tip:
Code:
for n in `seq 0 $number_lines `
do ...
prima, weil das zeilenweise auslesen immer wieder mal vorkommt. (kann kein perl...)

Wie wär's hiermit:
Code:
#!/bin/sh

	d0=$HOME'/Desktop/usr-bin'
	d1=$HOME'/Desktop/usr-bin-sl'

	for i in `cat $d0` ; do                                 

		if [ -z "$(grep $i $d1)" ] ; then echo $i ; fi
		
	done

Das ganze greift sowieso nicht so richtig:
Im Prinzip möchte ich sehen, daß auf meinem neuen System (Slackware 12.2) alle Programme installiert sind, die auch auf dem alten laufen (SuSE 9.3.). Da hier noch eine analoge Anbindung ist, Slackware noch nicht 'am Netz' ist und das Installieren der Software für Ungeübte nicht unbedingt einfach, möchte ich eine komplette Liste 'was denn noch so fehlt'.
Dabei gehts mir vor allem um das nicht so offensichtliche wie zB die psutils (die fehlen nicht).
Aber die 'Ausbeute' durch einen Vergleich der beiden /usr/bin-Verzeichnisse bringt eher magere Ergebnisse (da fehlt noch die Hälfte). Die lib's will ich lieber nicht vergleichen.
tom
 
A

Anonymous

Gast
OsunSeyi schrieb:
weil das zeilenweise auslesen immer wieder mal vorkommt. (kann kein perl...)
Code:
while read ZEILE
do
   echo "$ZEILE"
done < "$DATEINAME"
;) Bashcode möglichst immer so funktionell einfach wie irgendwie möglich halten, nichts noch zusätzlich verkomplizieren.

robi
 
OP
OsunSeyi

OsunSeyi

Hacker
Code:
read [-ers] [-u fd] [-t timeout] [-a aname] [-p prompt] [-n nchars] [-d delim] [name ...]
              One line is read from the standard input, or from the file descriptor fd supplied as an argument
              to  the -u option, and the first word is assigned to the first name, the second word to the sec-
              ond name, and so on, with leftover words and their intervening separators assigned to  the  last
              name.   If  there are fewer words read from the input stream than names, the remaining names are
              assigned empty values.  The characters in IFS are used to split the line into words.  The  back-
              slash  character  (\)  may be used to remove any special meaning for the next character read and
              for line continuation.  Options, if supplied, have the following meanings:
              -a aname
                     The words are assigned to sequential indices of the array variable aname, starting at  0.
                     aname is unset before any new values are assigned.  Other name arguments are ignored.
              -d delim
                     The first character of delim is used to terminate the input line, rather than newline.
              -e     If the standard input is coming from a terminal, readline (see READLINE above) is used to
                     obtain the line.
              -n nchars
                     read returns after reading nchars characters rather than waiting for a complete  line  of
                     input.
              -p prompt
                     Display  prompt  on standard error, without a trailing newline, before attempting to read
                     any input.  The prompt is displayed only if input is coming from a terminal.
              -r     Backslash does not act as an escape character.  The backslash is considered to be part of
                     the  line.   In  particular, a backslash-newline pair may not be used as a line continua-
                     tion.
              -s     Silent mode.  If input is coming from a terminal, characters are not echoed.
              -t timeout
                     Cause read to time out and return failure if a complete line of input is not read  within
                     timeout  seconds.  This option has no effect if read is not reading input from the termi-
                     nal or a pipe.
              -u fd  Read input from file descriptor fd.

              If no names are supplied, the line read is assigned to the variable REPLY.  The return  code  is
              zero,  unless  end-of-file is encountered, read times out, or an invalid file descriptor is sup-
              plied as the argument to -u.
Hmm.. soso :roll:
Also kann ich mit read zeilenweise auslesen?
Danke für den Tip!

Zum Vergleich der Programme:
"/opt/gnome/bin/grip" zB findet man so jedenfalls nicht..
tom
 

P6CNAT

Advanced Hacker
Hi,

OsunSeyi schrieb:
Wetten, nächste Woche siehst du selbst nicht mehr was du da zusammengeschustert hast.

Dem stimme ich zu, aber dem kann man mit folgendem Beispiel abhelfen.
Code:
#!/bin/ksh
################################################################################
#
#  Script-File   : .\bin\Name.sh
#  Author        : Name
#  Creation date : 07.10.2009
#  Description
#
#    Was passiert hier
#
#    Input parameter:
#       none
#
#  Changes
#
################################################################################
# set -vx
#-------------------------------------------------------------------------------
# Initialize variables
#-------------------------------------------------------------------------------


#-------------------------------------------------------------------------------
# 07.10.2009, Autor, hier beginnt der Code
#-------------------------------------------------------------------------------
:
:

Ok, braucht halt ein bischen Disziplin

Gruß
Georg
 
Oben