Автор Тема: Bourn shell скрипт  (Прочетена 12588 пъти)

bop_bop_mara

  • Напреднали
  • *****
  • Публикации: 2433
  • Distribution: Debian Testing
  • Window Manager: LXDE
  • Cute and cuddly
    • Профил
Активен

h4rd2kill

  • Участници
  • ***
  • Публикации: 8
    • Профил
Re: Bourn shell скрипт
« Отговор #16 -: Apr 08, 2012, 12:23 »
Здравейте,

Може ли да дадете някаква документация или обяснение както точно прави този ред:
Код:
set -- `getopt f:egh: "$@"`

До колкото четох това управлява командите, които се подавата.
Така в нашия случай f: изисква аргумент и h: също.
После не ми е точно ясно какво се случва с "$@" .

Мерси.
Активен

dev_urandom

  • Напреднали
  • *****
  • Публикации: 114
  • Distribution: Slackware
    • Профил
Re: Bourn shell скрипт
« Отговор #17 -: Apr 08, 2012, 18:08 »
Здравейте,

Може ли да дадете някаква документация или обяснение както точно прави този ред:
Код:
set -- `getopt f:egh: "$@"`

До колкото четох това управлява командите, които се подавата.
Така в нашия случай f: изисква аргумент и h: също.
После не ми е точно ясно какво се случва с "$@" .

Мерси.

http://tldp.org/LDP/abs/html/internalvariables.html#ARGLIST
Активен

radoulov

  • Напреднали
  • *****
  • Публикации: 116
    • Профил
Re: Bourn shell скрипт
« Отговор #18 -: Apr 08, 2012, 22:58 »
Цитат
До колкото четох това управлява командите, които се подавата.
Така в нашия случай f: изисква аргумент и h: също.

Правилно си разбрал.
Използвам getopt, за compatibility с bourne shell (bash, zsh и korn shell имат builtin getopts).
Виж man getopt за повече информация.


Виж също shelldorado (потърси Using "getopt").

Цитат
После не ми е точно ясно какво се случва с "$@" .

Обработват се един след друг (shift прави $2 -> $1,  $3 -> $2 и т.н.).
По този начин работим винаги с $1.

Код:
while [ $# -gt 0 ]; do
  case $1 in
 ...

И междувременно задаваме стойности на променливите _fname, _errexit, _zip и т.н.



Активен

gat3way

  • Напреднали
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Re: Bourn shell скрипт
« Отговор #19 -: Apr 09, 2012, 00:47 »
Ей, внимателно с това:

Цитат
[ -f /tmp/_kill_byte_ ] && rm /tmp/_kill_byte_

Някой шегаджия може да сътвори неприятни неща като symlink-ва /tmp/_kill_byte_ към нещо и чака root-а да изпълни скрипта за да го затрие :)

Колкото и да е тъпо, проверката с -f минава, ако симлинка сочи към истински съществуващ файл. И тъй като е ясно как трябва да се казва линка...:)
Активен

"Knowledge is power" - France is Bacon

radoulov

  • Напреднали
  • *****
  • Публикации: 116
    • Профил
Re: Bourn shell скрипт
« Отговор #20 -: Apr 09, 2012, 01:35 »
Ей, внимателно с това:

Цитат
[ -f /tmp/_kill_byte_ ] && rm /tmp/_kill_byte_

Някой шегаджия може да сътвори неприятни неща като symlink-ва /tmp/_kill_byte_ към нещо и чака root-а да изпълни скрипта за да го затрие :)

Колкото и да е тъпо, проверката с -f минава, ако симлинка сочи към истински съществуващ файл. И тъй като е ясно как трябва да се казва линка...:)

Good point!
И всичко това, защото bourne shell изпълнява while цикъла в subshell ...

По-добре би било:

Код:
[ -L  /tmp/_kill_byte_ ] || {
  [ -f /tmp/_kill_byte_ ] &&
    rm /tmp/_kill_byte_
    }
     

Активен

gat3way

  • Напреднали
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Re: Bourn shell скрипт
« Отговор #21 -: Apr 09, 2012, 01:50 »
Теоретично, дори така е възможно да race-не ако се създаде линка в много правилния момент. Примерно понеже после се пише в същият файл , можеш да се възползваш от това като линкнеш файла след проверката. Как - ами примерно пишеш програма, ползваща inotify, създаваш /tmp/_kill_byte (не symlink, а обикновен файл), чакаш за inotify събитието "изтриване на /tmp/_kill_byte" и го симлинкваш веднага след това. Последвалото писане в този файл ще помаже това, към което си го симлинкнал. Имаш добри шансове да успееш, шансовете се покачват на многоядрена машина :)

Но пък това става малко висш пилотаж на мизерията, трябва да е наистина голям шегаджия :)

Генерално решение иначе има - просто ползваш mktemp за временния файл и влошаваш живота на шегаджията доволно. Сега освен че трябва да направи този номер, трябва и да bruteforce-не случайното име на tempfile-а, нещо което вдига сложността с порядъци и го прави доста непрактично.
Активен

"Knowledge is power" - France is Bacon

radoulov

  • Напреднали
  • *****
  • Публикации: 116
    • Профил
Re: Bourn shell скрипт
« Отговор #22 -: Apr 09, 2012, 11:57 »
Да,
с mktemp ще е много по-сигурно.
Активен

sdr

  • Напреднали
  • *****
  • Публикации: 655
    • Профил
Re: Bourn shell скрипт
« Отговор #23 -: Apr 10, 2012, 12:08 »
при наличие на inotify за промяна в директорията колко по-труно ще бъде :)
Активен

gat3way

  • Напреднали
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Re: Bourn shell скрипт
« Отговор #24 -: Apr 10, 2012, 13:04 »
Доста по-трудно.

Kогато получиш IN_CREATE нотификацията, файлът вече е създаден и собственост на root (няма как да го затриеш, защото /tmp обикновено е със sticky бит). Т.е нищо не можеш да направиш вече.

Виж обаче ако можеше да го изтриеш, нещата щяха определено да загрубеят, тогава можеш да се възползваш от inotify за да затриеш и симлинкнеш tempfile-а....и накрая ще мине онзи ред в скрипта дето го трие и бум :)
Активен

"Knowledge is power" - France is Bacon

Naka

  • Напреднали
  • *****
  • Публикации: 3460
    • Профил
Re: Bourn shell скрипт
« Отговор #25 -: Apr 10, 2012, 19:52 »
//off

Сега като му шибнат някоя тройка :'( на скрипта на radoulov, ще ви пропаднат теориите за хубав скрипт. ;D
 [_]3
« Последна редакция: Apr 10, 2012, 19:54 от Naka »
Активен

Perl - the only language that looks the same before and after encryption.

radoulov

  • Напреднали
  • *****
  • Публикации: 116
    • Профил
Re: Bourn shell скрипт
« Отговор #26 -: Apr 10, 2012, 20:14 »
//off

Сега като му шибнат някоя тройка :'( на скрипта на radoulov, ще ви пропаднат теориите за хубав скрипт. ;D
 [_]3

Точно така.
Аз лично, не съм претендирал, че е хубав :)

П.С. И ако знех, че такова внимание ще му бъде обърнато,
щях да се постарая повече :)
« Последна редакция: Apr 10, 2012, 20:17 от radoulov »
Активен

Naka

  • Напреднали
  • *****
  • Публикации: 3460
    • Профил
Re: Bourn shell скрипт
« Отговор #27 -: Apr 10, 2012, 20:42 »

Точно така.
Аз лично, не съм претендирал, че е хубав :)

Ама ако му пишат 6, да вземе да почерпиш виртуално.
Активен

Perl - the only language that looks the same before and after encryption.

radoulov

  • Напреднали
  • *****
  • Публикации: 116
    • Профил
Re: Bourn shell скрипт
« Отговор #28 -: Apr 10, 2012, 20:47 »
Ама ако му пишат 6, да вземе да почерпиш виртуално.

Абе 6 няма да му пишат,
ама ако послужи за нещо, ще почерпя :)
Активен

radoulov

  • Напреднали
  • *****
  • Публикации: 116
    • Профил
Re: Bourn shell скрипт
« Отговор #29 -: Apr 10, 2012, 22:24 »
Много приказки са излишни :)
Нова версия:

Код:
#!/bin/sh

_fname= _errexit= _zip= _user_host=
_zip=/bin/bzip2
_ts=`date +%Y%m%d_%H%M%S`
_ext=bz2

_usage_msg="

usage: $0 -f <file_name>  -h user@host [ -e | -g ]

  -f file name containing pathnames
  -e exit if path does not exists
  -g use gzip (otherwise bzip2)
  -h remote user@host

"

die() {
  printf >&2 '%s\n' "$@"
  exit 1
  }

[ $# -lt 1 ] && die "$_usage_msg"

# This commands do not work with all shells,
# because the set command does not always return an error code
# if getopt fails
set -- `getopt f:egh: "$@"` ||
  die "$_usage_msg"

while [ $# -gt 0 ]; do
  case $1 in
     -f ) shift;  _fname=$1; shift ;;
     -e ) shift; _errexit=on ;;
     -g ) shift; _zip=/bin/gzip _ext=gz ;;
     -h ) shift; _user_host=$1; shift ;;
     -- ) break ;;
  esac
done

[ -r "$_fname" ] || die "invalid filename: $_fname"

case $_user_host in
   *@* )                                 ;;
    *  ) die "invalid host: $_user_host" ;;
esac

touch arch_"$_ts".tar

while IFS= read f; do
  [ -f "$f" ] && [ ! -L "$f" ] || {
    [ "$_errexit" ] &&
      die "invalid path: $f" ||
     continue
     }
  tar uf arch_"$_ts".tar "$f" ||
    die 'tar failed'
done < "$_fname" ||
  exit 1


"$_zip" arch_"$_ts".tar ||
  die 'compressing archive file failed'

scp arch_"$_ts.tar.$_ext" "$_user_host": ||
  die 'scp failed'




Прочитайки отново пост #1, реших, че може да не съм разбрал правилно.
Въпросът е с повишена трудност, ако, както бях разбрал, скриптът трябва да работи
със старата Bourne shell (за да съм по-ясен: /bin/shell на Solaris
[the old Bourne shell], не /usr/bin/shell на HP-UX [която всъщност е ksh88]).

Ако в действителност изискването е скриптът да е стандартен/POSIX - нещата стават
мнооого по-лесни :)

С -e в някой случаи може да остане (частичен) tar file.
Ако това не е желателно, виждайки, че сме малко параноични,
ще трябва да се работи първо върху временен file
(име генерирано с mktemp :)) който да се преименува само след успешно архивиране.

« Последна редакция: Apr 11, 2012, 11:37 от radoulov »
Активен


Подобни теми
Заглавие Започната от Отговора Прегледи Последна публикация
Shell картинка
Настройка на програми
Hanibal 0 3271 Последна публикация Jan 08, 2007, 00:35
от Hanibal
Shell скрипт за актуализация на папка
Общ форум
Radev 13 5417 Последна публикация Feb 11, 2007, 13:51
от radoulov
Проблем със shell конзолата
Кошче
madmad 2 3384 Последна публикация Sep 17, 2007, 23:04
от alabal
Проблем с Shell скрипт за НТВ
Настройка на програми
GuessWho 2 3600 Последна публикация Mar 14, 2009, 13:17
от GuessWho
Безплатен Shell Акаунт
Настройка на програми
madmad 2 3882 Последна публикация Jun 28, 2010, 18:03
от betso