Вопрос или проблема
Я хочу иметь возможность отображать файлы в указанной директории, выбрать один из файлов и иметь возможность удалить его.
Вот что я нашел на данный момент. Может кто-то помочь?
let i=0 # определить счетную переменную
W=() # определить рабочий массив
while read -r line; do # обрабатывать файл за файлом
let i=$i+1
W+=($i "$line")
done < <( ls -1 /home/admin/Desktop )
FILE=$(dialog --title "Список файлов в директории /home" --menu "Выберите один" 24 80 17 "${W[@]}" 3>&2 2>&1 1>&3) # показать диалог и сохранить вывод
clear
if [ $? -eq 0 ]; then # Выйти с OK
readlink -f $(ls -1 /home | sed -n "`echo "$FILE p" | sed 's/ //'`")
fi
Скрипт использует возвращаемое значение из dialog
, чтобы выбрать элемент из списка файлов (или директорий) в указанной директории.
Проблема с bash-скриптом в том, что он использует два разных значения директории:
let i=0 # определить счетную переменную
W=() # определить рабочий массив
while read -r line; do # обрабатывать файл за файлом
let i=$i+1
W+=($i "$line")
done < <( ls -1 /home/admin/Desktop )
FILE=$(dialog --title "Список файлов в директории /home" --menu "Выберите один" 24 80 17 "${W[@]}" 3>&2 2>&1 1>&3) # показать диалог и сохранить вывод
clear
if [ $? -eq 0 ]; then # Выйти с OK
readlink -f $(ls -1 /home | sed -n "`echo "$FILE p" | sed 's/ //'`")
fi
Это /home/admin/Desktop
и /home
. Обычная практика сделала бы их символом (т.е. переменной) и устранила бы несоответствие:
#!/bin/bash
source=/home/admin/desktop
let i=0 # определить счетную переменную
W=() # определить рабочий массив
while read -r line; do # обрабатывать файл за файлом
let i=$i+1
W+=($i "$line")
done < <( ls -1 $source )
FILE=$(dialog --title "Список файлов в директории $source" --menu "Выберите один" 24 80 17 "${W[@]}" 3>&2 2>&1 1>&3) # показать диалог и сохранить вывод
clear
if [ $? -eq 0 ]; then # Выйти с OK
readlink -f $source/$(ls -1 $source | sed -n "`echo "$FILE p" | sed 's/ //'`")
fi
Сделав это, результат из readlink
станет пригодным для использования.
Скрипт с этой исправленной версией не завершен:
- он фактически не удаляет файл
- он не проверяет, является ли элемент для удаления файлом или директорией
- использование вывода
ls
(дважды!) не является лучшим способом получения списка
Ответ или решение
Конечно, я помогу вам разобраться с задачей создания диалогового меню для отображения файлов в заданной директории, выбора одного из них и его последующего удаления. Давайте подробно рассмотрим решение, основываясь на ваших требованиях и предоставленном вами коде.
Теория
Основы Bash скриптов и утилиты dialog
Bash скрипты — это мощный инструмент для автоматизации задач в Linux. Они позволяют выполнять последовательности команд, принимать входные данные от пользователя и отображать результаты. В данном случае, вам необходимо использовать утилиту dialog
, которая позволяет создавать диалоговые окна в текстовом интерфейсе, что очень полезно для интерактивных скриптов.
Проблемы текущего скрипта
Ваш текущий скрипт имеет несколько недоработок:
- Несоответствие директорий: Вы используете две разные директории (
/home/admin/Desktop
и/home
), что может привести к ошибкам. - Отсутствие функциональности удаления: Скрипт не выполняет удаление выбранного файла.
- Недостаточная проверка типов файлов: Нет проверки, является ли выбранный элемент файлом или директорией.
- Неправильное использование
ls
: Использованиеls
для получения списка файлов может привести к проблемам с пробелами в именах файлов. Лучше использовать команды, поддерживающие нулевой символ как разделитель.
Рекомендации по улучшению
- Унифицированный путь: Используйте переменную для хранения пути к директории.
- Удаление файлов: Используйте команду
rm
для удаления выбранного файла, предварительно проверяя его существование. - Проверка типа файла: Используйте команду
file
или встроенные проверки Bash для определения, является ли элемент файлом. - Корректное извлечение списка файлов: Используйте команды
find
илиmapfile
для более надежного получения списка файлов.
Пример
Вот пример того, как ваш скрипт может быть улучшен:
#!/bin/bash
# Устанавливаем директорию
source_dir="/home/admin/Desktop"
# Инициализация счетчика и массива
let i=0
W=()
# Получаем список файлов и формируем массив для dialog
while IFS= read -r -d '' line; do
let i=$i+1
W+=($i "$line")
done < <(find "$source_dir" -maxdepth 1 -type f -print0)
# Показываем диалоговое окно с выбором файла
FILE_NUM=$(dialog --title "Список файлов в директории $source_dir" --menu "Выберите файл" 24 80 17 "${W[@]}" 3>&2 2>&1 1>&3)
clear
# Проверяем успешность закрытия окна
if [ $? -eq 0 ]; then
# Получаем имя файла
FILE_NAME=$(printf "%s\n" "${W[$(( FILE_NUM * 2 - 1))]}")
# Подтверждение удаления
dialog --yesno "Вы уверены, что хотите удалить файл '$FILE_NAME'?" 7 60
if [ $? -eq 0 ]; then
# Удаляем файл и проверяем успешность операции
if rm "$source_dir/$FILE_NAME"; then
dialog --msgbox "Файл успешно удален." 5 40
else
dialog --msgbox "Ошибка при удалении файла." 5 40
fi
fi
fi
Применение
Как использовать
Запустите скрипт в терминале. Скрипт отобразит диалоговое меню со списком файлов в выбранной директории. После выбора файла будет предложено подтвердить его удаление.
Преимущества улучшенного скрипта
- Безопасное удаление: Скрипт проверяет, действительно ли выбранный элемент — файл, перед его удалением.
- Унифицированность: Все операции происходят в рамках одной директории, что уменьшает вероятность ошибки.
- Юзер-френдли интерфейс: Взаимодействие через диалоговое окно упрощает использование.
Такой подход обеспечивает более точное и безопасное выполнение поставленной задачи, что особенно важно в контексте удаления файлов, где ошибки могут стоить дорого.