2009-11-23 5 views
0

Я не совсем новичок в программировании, но я не очень опытен. Я хочу написать небольшой сценарий оболочки для практики.Bourne Shell Scripting - простой для петлевого синтаксиса

Вот что я до сих пор:

#!/bin/sh 
name=$0 
links=$3 
owner=$4 
if [ $# -ne 1 ] 
then 
     echo "Usage: $0 <directory>" 
     exit 1 
fi 
if [ ! -e $1 ] 
then 
     echo "$1 not found" 
     exit 1 

elif [ -d $1 ] 
then 
     echo "Name\t\tLinks\t\tOwner\t\tDate" 
     echo "$name\t$links\t$owner\t$date" 
     exit 0 
fi 

В основном то, что я пытаюсь сделать, это скрипт пройти через все файлы в указанной директории, а затем отобразить имя каждого файла с количество ссылок, его владельца и дату его создания. Каким будет синтаксис для отображения даты создания или, по крайней мере, даты последней модификации файла?

Другое дело, что такое синтаксис для создания цикла for? Насколько я понимаю, мне пришлось бы написать что-то вроде $ 1 в $ 1 ($ 1 - все файлы в каталоге, который пользователь вводил правильно?), А затем проверить каждый файл и отобразить информацию для каждого из них. Как мне начать и закончить цикл for (для чего это синтаксис?).

Как вы можете видеть, я не очень хорошо знаком с программированием ракеты bourne. Если у вас есть полезные сайты или у вас есть лучший способ приблизиться к этому, пожалуйста, покажите мне!

ответ

4

Синтаксис для цикла:

for var in list 
do 
    echo $var 
done 

, например:

for var in * 
do 
    echo $var 
done 

Что вы могли бы хотеть рассмотреть, однако, что-то вроде этого:

ls -l | while read perms links owner group size date1 date2 time filename 
do 
    echo $filename 
done 

который разделяет выход от ls -l в полеты на лету, поэтому вам не нужно делать какие-либо расщепления самостоятельно.

Разделение поля управляется переменной IFS оболочки, которая по умолчанию содержит пробел, вкладку и новую строку. Если вы измените это в сценарии оболочки, не забудьте изменить его. Таким образом, изменяя значение IFS, вы можете, например, разобрать CSV-файлы, установив это в запятую. Этот пример читает три поля из CSV и выплевывает 2-й и третий только (это эффективна оболочка эквивалент cut -d, -f2,3 inputfile.csv)

oldifs=$IFS 
IFS="," 
while read field1 field2 field3 
do 
    echo $field2 $field3 
done < inputfile.csv 
IFS=oldifs 

(примечание: вы не необходимости вновь обратиться IFS, но я вообще делаю чтобы дальнейшая обработка текста в скрипте не была затронута после того, как я покончу с этим).

Огромное количество документации на обеих for и while петлях; просто Google для него :-)

+0

У вас есть избыточный (и вредный) знак доллара в ваших циклах. Он должен быть 'для var in *; do ... done', без '' 'перед' var'. – ndim

+0

А вы правы, а цикл будет более эффективным. Спасибо за советы и объяснение синтаксиса. –

+0

@ndim - хорошо поймать, исправлено. Я только что вышел из игры с перлом в течение последнего часа. У меня есть пунктуация, плавающая перед моими глазами ... :-) –

2

Возможно, вы захотите посмотреть Advanced Bash-Scripting Guide. В нем есть раздел, в котором описываются циклы.

+0

Спасибо за сайт, он очень организован. –

2

Я предлагаю использовать find с опцией -printf "%P\t%n\t%u\t%t"

1
for x in "[email protected]"; do 
    echo "$x" 
done 

«$ @» защищает любые пробелы в поставляемых имен файлов. Очевидно, сделайте свою настоящую работу вместо «echo $ x», что мало что делает. Но $ @ - это все мусор, предоставленный в командной строке для вашего скрипта.

Но и ваш скрипт выдается, если $ # не равно 1, но вы, по-видимому, полностью ожидаете до 4 аргументов (следовательно, 4 доллара вы ссылаетесь в начале своего скрипта).

1

предполагается, что вы GNU найти в вашей системе

find /path -type f -printf "filename: %f | hardlinks: %n| owner: %u | time: %TH %Tb %TY\n" 
2

$1 является первым позиционным параметром, поэтому $3 является третьим и $4 является четвертым. Они не имеют ничего общего с каталогом (или его файлами), с которого был запущен скрипт. Если ваш скрипт начал использовать это, например:

./script.sh apple banana cherry date elderberry 

тогда переменная $1 будет равна «яблоко» и так далее. Специальный параметр $# - это счетчик позиционных параметров, который в этом случае будет равен пяти.

Название сценария содержится в $0 ии [email protected] - это массивы, которые содержат все позиционные параметры, которые ведут себя по-разному в зависимости от того, отображаются ли они в кавычках.

Вы можете обратиться к позиционным параметрам, используя индекс подстроки в стиле:

${@:2:1} 

даст «банан», используя пример выше. И:

${@: -1} 

или

${@:$#} 

даст последний ("бузины"). Обратите внимание, что в этом контексте требуется пробел перед знаком минус.