![список файлов и сохранение его в переменных](https://rvso.com/image/38694/%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%20%D1%84%D0%B0%D0%B9%D0%BB%D0%BE%D0%B2%20%D0%B8%20%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5%20%D0%B5%D0%B3%D0%BE%20%D0%B2%20%D0%BF%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D1%8B%D1%85.png)
Я новичок в программировании оболочки. Моя цель — предоставить пользователю выбор, какой файл следует запустить. Я перехватываю все доступные скрипты в одной переменной с помощью:
var=$(find script*)
пока все хорошо, вот результат:
echo $var
script1 script2 script3 scr...
Теперь я хочу сохранить каждый файл в отдельной переменной, чтобы запустить его при последующем выборе.
select SEL in script1 script2 script3 ..........
case $SEL in
$Script1) echo ($Script1 will start) && ./$script1 ;;
$Script2) echo ($Script2 will start) && ./$script2 ;;
$Script3) echo ($Script3 will start) && ./$script3 ;;
$Sc..) echo ($Scr.... will start) && ./$scrip.... ;;
$Sc...) echo ($Sc...... will start) && ./$scrip..... ;;
*) echo "choose on of the availabel files";;
esac
done
Я понятия не имею, как мне разделить все файлы, если я не знаю их количество и точную длину каждого файла.
Я пробовал разделить с помощью echo ${var[1]} и echo $var[1], но это не работает. Я получаю либо пустой вывод, либо целую строку.
решение1
Ваша первая строка:
var=$(find script*)
просто создает var
одну строковую переменную со всеми script*
в ней. Этонетмассив, поэтому мы не можем индексировать его так, []
как вам хочется.
На самом деле расширяется script*
оболочкой, так что find
ничего там не делает (если только это не каталоги, на которые, похоже, они не похожи) — он просто получает все имена файлов в качестве аргументов, проверяет их существование и выводит их обратно. На самом деле всю работу делает оболочка..
Вместо этого мы можем сделатьмножество, и мы можем использовать оболочкурасширение глобуснепосредственно для его заполнения:
files=(script*)
Когда мы заключаем инициализатор (правая часть =
) в скобки, мы создаем массив, который содержит несколько значений по отдельности. script*
расширится до каждого имени файла, начинающегося с script
в текущем каталоге. Если в именах файлов есть пробелы, они не приведут к тому, что слова будут разделены так, как это было бы с командами (обратными кавычками или $()
) внутри инициализатора массива.
На этом этапе мы можем прочитать некоторые данные, введенные пользователем:
select SEL in "${files[@]}"
do
if ! [ "$SEL" ]
then
echo "Choose one of the available files."
continue
fi
echo "$SEL will start"
"./$SEL"
break
done
Мы пишем "${files[@]}"
, чтобы развернуть весь наш массив имен файлов чисто, чтобы дать select
. Пользователю будет предложен выбор файлов, а затем мы входим в do...done
блок.
Если $SEL
пусто, пользователь выбрал несуществующую запись, поэтому мы выводим подсказку и continue
предлагаем ему сделать выбор еще раз.
В противном случае мы echo
получаем уведомление о том, что скрипт запустится и запустит скрипт. Мы заключаем имя в кавычки, "./$SEL"
если в имени скрипта есть пробелы, которые в противном случае привели бы к тому, что имя команды будет рассматриваться как ./firstword
, а остальные слова — как аргументы. break
останавливает нас от повторного обращения к пользователю; если вы хотите это сделать, уберите его.
То, что case...of
вы использовали, похоже, не оказывает большого эффекта в приведенном вами примере, но если у вас есть какое-то отдельное поведение в зависимости от выбранного скрипта (и он должен быть вэтотскрипт), вы можете поместить его внутрь do...done
блока.
решение2
Не уверен на 100%, что полностью понимаю, что вы хотите сделать, но это может сработать для вас лучше: Вместо var=$(find script*) и case вы могли бы лучше использовать
for i in `find script*`
do
echo ($i will start)
./$i
done