PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Wie Dateien aus Datei auslesen?



nobody0
14-09-2005, 00:11
Um einige Dateien auf einigen Servern upzudaten und dort für jeden lesbar zu machen (über ftp/http) erstelle ich in einem Skript erstmal eine Liste:

...
touch $FILE_LIST
# set length to zero
> $FILE_LIST
for f in c/*.c ; do
echo ${f%.c} >> $FILE_LIST
done
...

und diese Liste wird dann per rsync upgedatet:

...
rsync -vxSH -e ssh --include-from=$FILE_LIST r0@192.168.39.9:$SERVER_ROOT
...

und das funktioniert soweit.
Vorher sollen aber die Dateien der Liste, also die in $FILE_LIST, für alle lesabar gemacht werden (chmod a+rX), da die Dateien sonst auf den Servern quasi verschwinden, da sie sonst nur für den user lesbar sind.
Wie bekommt man das hin? :confused:

Die Dateinamen sind harmlos, also ohne Leerzeichen, ohne Newlines (hatte ich schon mehrmals gefunden) und anderem Unfug im Dateinamen.
Ansonsten würde auch das Format der Temporär-Datei - pro Dateinamen eine Zeile - nicht funktionieren.

michael.sprick
14-09-2005, 07:19
Könntest Du das chmod nicht direkt in Deine for-Schleife bauen?



for f in c/*.c ; do
chmod a+rX ${f}
echo ${f%.c} >> $FILE_LIST
done

nobody0
14-09-2005, 09:05
Machbar, aber das schränkt die Dateianzahl ein; bei ca. 32636 ist bei der Bash schluss.
Mit einer Datei und For-Schleife ist das Limit nur die Dateigrösse.

michael.sprick
14-09-2005, 10:07
hmmm.. versteh ich nicht ganz.
Wenn das chmod doch in der Schleife ist, werden ja immer nur die Attribute _einer_ Datei geändert.

Und die inwiefern spielt die Dateigröße eine Rolle bei der vergabe von Dateirechten?

oder meintest Du, dass die for-Schleife einfach nicht durchläuft? Dann kann das aber eigentlich nix mit chmod zu tun haben...

Alternativ kannst Du ja eine while-Schleife nehmen:



while [ "$1" ]; do
file=$1
#tu etwas...
shift
done


und dann das Skript mit
script.sh c/*.c aufrufen.

Ansonsten erklär nochmal genau was passiert...

quinte17
14-09-2005, 10:44
dass * ist der haken...
wenn du 3 dateien hast
a.txt
b.txt
c.txt
und sagst nun
vi *.txt
so macht die bash daraus:
vi a.txt b.txt c.txt
und die meisten die eine bash haben können "nur" diese besagten 32 tausend parameter übergeben...

somit ist bei 32k nunmal schluß...

greetz

michael.sprick
14-09-2005, 11:54
ach echt? Parametersubstitution ist begrenzt auf ca. 32000?
Hmm..

na, dann vielleicht ein Perlskript?


#!/usr/bin/perl

use strict;
use warnings;

my $dir = 'c';
opendir(DH,$dir);
while(my $file = readdir(DH))
{
#tu was....
}

nobody0
15-09-2005, 16:00
Ich dachte daran, die Liste in eine Datei zu schreiben und dann einzeln abzuarbeiten.
Schliesslich kann die Datei auf Rechnern mit wenig RAM grösser als das RAM werden und mit der Datei ist immer protokolliert, was upgedatet wird, selbst wenn das Skript schon vor dem Ende terminiert wird.

nobody0
15-09-2005, 16:25
Mit google konnte ich was finden, hier mit dem Beispiel /etc/fstab:



#!/bin/bash
#
# Hier wird die Standardeigabe auf den Filedeskriptor 3< umgeleitet und die
# Datei /etc/fstab wird nach 0< (zuvor stdin) gelenkt. Anschliessend wird mit
# dem Befehl read Zeile fuer Zeile bis EOF gelesen.

exec 3<&0 0< /etc/fstab

# integer i for line counting
typeset -i i=0

while read line
do
echo -e "$line"
i=i+1
done

echo "Found $i lines."

exit 0

rais
18-09-2005, 22:33
Moin,
redet ihr nich aneinander vorbei?
Michael hat Dir doch schon die passende Antwort gegeben - und das in seiner Ersten... statt erst alles in die Liste zu packen, die _einzelne_ Datei a+rX zu machen - das hat er auch bereits gesagt.

Aber wenn Du drauf bestehst, erst die Liste zu generieren und danach erst den chmod auf die Listenelemente drauf loszulassen:


:
for I in `cat $FILE_LIST`; do
f=${I}.c #Du hast ja die Endung abgeschnitten...
test -r ${f} && chmod a+rX ${f}
done

Den Test kannst Du natürlich weglassen, wenn die Liste wirklich nur aus den c/*.c (ohne .c) Einträgen besteht :D
MfG,