Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: задачка на bash  (Прочитано 11719 раз)
0 Пользователей и 1 Гость смотрят эту тему.
ZWYHB
Участник

ru
Offline Offline

« : 26-11-2009 13:52 » 

 Разработать сценарий для поддержки базы данных входящих документов
Документ представлен некоторым текстовым файлом. База данных - это отдельный каталог, в котором размещаются документы. Требуется
-добавить документ в базу
-просмотреть список документов
-отобразить содержимое документов
-получить объём в байтах документа
Работа с системой с помощью меню и задании параметров, необходимых для выполнения соотв. действия. После выполнения действия пользователю опять предлагается выыбрать один из пунктов меню
Завершение работы осуществляется посредством выбора Выход

Вот это - После выполнения действия пользователю опять предлагается выбрать один из пунктов меню -
можно вот так реализовать через while true, т.е

Код:
while true

do

PS3="Выберите пункт меню:"

select ITEM in "Открыть файл" "Добавить документ в базу" "Получить объем в байтах" "Выход"
do

case $ITEM in
"Открыть файл") OPEN;
esac


case $ITEM in
"Добавить документ в базу") ADDD;
esac

case $ITEM in
"Получить объем в байтах") INFO;
esac

case $ITEM in
"Выход")
esac
break;
done

и описание функций здесь правильно, а то я первый раз пишу на bash
while true

Код:
VHOD() 
{
echo Введите путь к каталогу
read FOLDER
cd $FOLDER
#cd /home/an/lab2
echo Список документов в выбранном каталоге:
ls
}
VHOD

OPEN()
{
echo Введите имя файла
read INPUT
if [ ! -e $INPUT ]; then
echo Нету такого файла; OPEN
elif [  -e  $INPUT ]; then
cat $INPUT
continue
fi
}

INFO()
{
echo Введите имя файла информацию о котором хотите узнать:
read INPUT
echo Размер  Имя файла; du $INPUT
}


ADDD()
{
count=0
echo Введите файл:
read INPUT
touch $INPUT
}
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 26-11-2009 15:00 » 

ZWYHB, прежде всего — используй отступы для форматирования - иначе плохо читается текст программы.

Цитата
select ITEM in ...

Вообще-то, команда называется for, а не select.

Цитата
while true
do
  ...
  break;
done

Бессмыслица.

Это на первый взгляд — позже возможно еще найдется.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Sla
Модератор

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 26-11-2009 16:03 » 

RXL,
Цитата
select name [ in word ] ; do list ; done
              The list of words following in is expanded, generating a list of
              items.  The set of expanded words is  printed  on  the  standard
              error,  each  preceded  by a number.  If the in word is omitted,
              the positional parameters are printed  (see  PARAMETERS  below).
              The  PS3 prompt is then displayed and a line read from the stan-
              dard input.  If the line consists of a number  corresponding  to
              one  of  the  displayed  words, then the value of name is set to
              that word.  If the line is empty, the words and prompt are  dis-
              played again.  If EOF is read, the command completes.  Any other
              value read causes name to be set to  null.   The  line  read  is
              saved  in  the  variable REPLY.  The list is executed after each
              selection until a break command is executed.  The exit status of
              select  is the exit status of the last command executed in list,
              or zero if no commands were executed.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 26-11-2009 17:51 » 

Sla, буду знать.
Однако... За 11 лет скриптописательства эта команда ни разу не понадобилась и ни разу не видел в чужих скриптах. Обычно для перебора используют for in, а для ввода - read.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 26-11-2009 18:07 » 

ZWYHB,

Цитата
Код:
VHOD() 
{
echo Введите путь к каталогу
read FOLDER
cd $FOLDER
#cd /home/an/lab2
echo Список документов в выбранном каталоге:
ls
}
VHOD

1. Зачем объявлять функцию, если используется она однажды и в том же месте?

2. После read и перед cd полезно проверить, есть ли такая директория:
Код:
  echo 'Введите путь к каталогу'
  read FOLDER

  while [ ! -d "$FOLDER" ]
  do
    echo -ne 'Такой директории не существует! Попробуйте еще раз.\nВведите путь:'
    read FOLDER
  done

  cd "$FOLDER"
  echo 'Список документов в выбранном каталоге:'
  ls

Поясняю свой код:

1. Строки беру в кавычки. Если их не надо интерполировать (не содержат переменных для вставки), то лучше обернуть их одинарными кавычками. Если надо, то можно и двойными, но следует делать это осторожно.

2. Переменную FOLDER при проверке и в cd я обернул двойными кавычками, т.к. путь может содержать пробелы и строка, полученная после интерполяции, порежется на параметры по пробелам. Пример для понимания:

Код:
[rxl@home-gw ~]$ touch 'aaa bbb'
[rxl@home-gw ~]$ ls -l aaa bbb
ls: aaa: No such file or directory
ls: bbb: No such file or directory
[rxl@home-gw ~]$ ls -l 'aaa bbb'
-rw-rw-r-- 1 rxl rxl 0 Nov 26 21:02 aaa bbb
[rxl@home-gw ~]$

Тоже с переменной:

Код:
[rxl@home-gw ~]$ mkdir 'aaa bbb'
[rxl@home-gw ~]$ FOLDER='aaa bbb'
[rxl@home-gw ~]$ pwd
/home/rxl
[rxl@home-gw ~]$ cd $FOLDER
-bash: cd: aaa: No such file or directory
[rxl@home-gw ~]$ cd "$FOLDER"
[rxl@home-gw aaa bbb]$ pwd
/home/rxl/aaa bbb
[rxl@home-gw aaa bbb]$

У тебя эта ошибка присутствует повсеместно.

3. "echo -ne": параметр -n убирает перевод строки в конце вывода, а пареметр -e разрешает escape-последовательности с бекслешом (в стиле C/C++) и позволяет указывать выводить такие символы, как табуляции и переводы строк, в нужном месте.
« Последнее редактирование: 26-11-2009 18:15 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
ZWYHB
Участник

ru
Offline Offline

« Ответ #5 : 26-11-2009 18:45 » 

так со VHODом всё понятно, а как же тогда сделать так, чтобы после выполнения действия пользователю опять предлагалось выбрать один из пунктов меню ?
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #6 : 26-11-2009 19:02 » 

ZWYHB, давай начнем с самого важного для новичка — с наведения порядка.
Возьмем пока второй кусок.

Я его только слегка почистил и добавил недостающий done в конце. Сравни с оригиналом:

Код:
while true
do
  PS3="Выберите пункт меню:"

  select ITEM in "Открыть файл" "Добавить документ в базу" "Получить объем в байтах" "Выход"
  do
    case $ITEM in
      "Открыть файл") OPEN;
    esac

    case $ITEM in
      "Добавить документ в базу") ADDD;
    esac

    case $ITEM in
      "Получить объем в байтах") INFO;
    esac

    case $ITEM in
      "Выход")
    esac

    break
  done
done

Уже читается лучше!

Команда case работает аналогично оператору switch С/С++/Java/PHP и пр.: одно входящее значение и набор условий. Конец каждого блока в case обозначается двумя точка-с-запятой.

Бесконечный цикл while true - это не хорошо. Надо делать естественное завершение программы. Кроме того, у тебя роль цикла выполняет select-do-done - зачем еще делать while true вокруг него?

Вот исправленный вариант:

Код:
PS3="Выберите пункт меню:" 

select ITEM in "Открыть файл" "Добавить документ в базу" "Получить объем в байтах" "Выход"
do
  case $ITEM in
    "Открыть файл")
      OPEN
      ;;
    "Добавить документ в базу")
      ADDD
      ;;
    "Получить объем в байтах")
      INFO
      ;;
    "Выход")
      break
      ;;
  esac
done
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
ZWYHB
Участник

ru
Offline Offline

« Ответ #7 : 26-11-2009 19:22 » 

Спасибо, а получение объёма в байтах документа здесь правильно реализовано:
Код:
INFO() 
{

echo Введите имя файла информацию о котором хотите узнать:

read INPUT

echo Размер  Имя файла; du $INPUT
}
?
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #8 : 26-11-2009 19:33 » 

А проверить, вообше это файл или нет?
Код:
if [ -f $input ] ; then 
   echo Имя файла $input, размер $(du $input|cut -f1);
fi
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 26-11-2009 19:47 » 

man du

По умолчанию показывает все физическое место в 1 кБ блоках, занятое файлом.
Так покажет размер файла в байтах, без учета неиспользуемого места:

du -b "filename"

« Последнее редактирование: 26-11-2009 19:50 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #10 : 26-11-2009 19:52 » 

Цитата
Код:
echo Размер  Имя файла; du $INPUT

1. $INPUT следует обернуть двойными кавычками. Я это уже дважды говорил!

2. Вопрос на засыпку: для чего тут точка с запятой перед du? (вопрос только к ZWYHB)
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
ZWYHB
Участник

ru
Offline Offline

« Ответ #11 : 27-11-2009 08:21 » 

RXL, хороший вопрос!
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #12 : 28-11-2009 08:20 » 

ZWYHB, для продолжения дискуссии жду ответа. Вопрос элементарный. Если те строчки были написаны тобой, ответа ты не знать не можешь.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines