Как я могу использовать функцию, которая читает переменную?

#!/bin/bash declare -a a=(`ls`) var=0 while [ -n "${a[$var]}" ] do var=`expr $var + 1` done Pdir(){ if[ "`stat -c %F ${a[$i]}`" = "directory" ] then echo " __ " echo "/---/ |" echo "| d |" echo "--------" echo "${a[$i]}" else echo "nope" fi } for((i=0; i < var ; i++)) do Pdir($i) done

Это мой код. То, что я хочу сделать, - это когда я нахожу каталог и печатаю:

__ /---/ | | d | -------- "filename"
6
задан 11 June 2017 в 10:57

3 ответа

Вы можете использовать shell glob */ для соответствия только каталогам, тем самым устраняя необходимость в отдельной проверке каталога:

a=(*/)

Ваш первый цикл не нужен - все, что он делает, - это подсчет элементов в массиве, который вы можете использовать с помощью ${#a[@]}

. В любом случае вам не нужно знать количество элементов, чтобы их перебрать - вы можете использовать

for i in "${a[@]}"; do Pdir "$i" done

Также printf лучше, чем эхо. Итак,

#!/bin/bash Pdir(){ printf '%s\n%s\n%s\n%s\n' \ " __ " \ "/---/ |" \ "| d |" \ "--------" \ "$1" } shopt -s nullglob dirs=(*/) for d in "${dirs[@]}"; do Pdir "$d" done

Если вы хотите обработать все файлы, т.е. a=(*), и проверить их явно, то вместо использования stat вы можете использовать прямой тест оболочки [ ! d6] [ -d "$i" ]

(запустите help test в оболочке, чтобы увидеть параметры).

8
ответ дан 18 July 2018 в 11:52

Ваш вызов функции неверен:

Pdir($i) # this is wrong

В Bash вы вызываете функции так же, как вы вызываете двоичные исполняемые файлы, записывая их имя как команду и помещая все аргументы за ней, разделенные пробелами и не заключенные в какие-либо скобки:

Pdir $i # this is correct, but not good

Обратите внимание, что вы должны всегда всегда ставить переменные в двойные кавычки, чтобы они не могли разделиться и интерпретироваться как несколько аргументов, если они содержат пробелы, поэтому оптимальные способ написать:

Pdir "$i" # this is how you do it

Еще одна крошечная ошибка в том, что вам нужно пространство между тестом if и [.

Вы также должны повторить эту переменную, и вместо `...` рекомендуется использовать более современный синтаксис подстановки команды $(...). Обратите внимание, что двойные кавычки внутри скобок подстановки команд разрешены, даже если сама замена окружена двойными кавычками.

if [ "$(stat -c %F "${a[$i]}")" = "directory" ]

И вместо интерпретации вывода ls (почему не разобрать ls?), лучше получить массив файлов и каталогов в текущем каталоге, например используя оболочку glob:

a=(*)

Обратите внимание, что по умолчанию это возвращает только не скрытые файлы, то есть все, что не начинается с точки. Чтобы также просмотреть скрытые файлы и каталоги, включите опцию оболочки dotglob внутри вашего скрипта один раз:

shopt -s dotglob a=(*)
12
ответ дан 24 July 2018 в 19:52

Вы можете использовать shell glob */ для соответствия только каталогам, тем самым устраняя необходимость в отдельной проверке каталога:

a=(*/)

Ваш первый цикл не нужен - все, что он делает, - это подсчет элементов в массиве, который вы можете использовать с помощью ${#a[@]}

. В любом случае вам не нужно знать количество элементов, чтобы их перебрать - вы можете использовать

for i in "${a[@]}"; do Pdir "$i" done

Также printf лучше, чем эхо. Итак,

#!/bin/bash Pdir(){ printf '%s\n%s\n%s\n%s\n' \ " __ " \ "/---/ |" \ "| d |" \ "--------" \ "$1" } shopt -s nullglob dirs=(*/) for d in "${dirs[@]}"; do Pdir "$d" done

Если вы хотите обработать все файлы, т.е. a=(*), и проверить их явно, то вместо использования stat вы можете использовать прямой тест оболочки [ ! d6] [ -d "$i" ]

(запустите help test в оболочке, чтобы увидеть параметры).

8
ответ дан 24 July 2018 в 19:52

Другие вопросы по тегам:

Похожие вопросы: