bash script - ошибка перехода в каталог с тильдой

На самом деле это единственный раздел про unix на этом форуме

Модератор: /dev/random

Аватара пользователя
sunjob
Сообщения: 121

bash script - ошибка перехода в каталог с тильдой

Сообщение sunjob » 26.10.2015 02:18

в функцию на баше отправляется параметр "путь к другому скрипту с тильдой", вида

Код: Выделить всё

~/PATH_TO_FILE/FILE

в функции происходит парсинг на путь и имя файла, при попытке перейти в каталог, выдается сообщение ошибки
если тут же копипастом вставить к ком. строку просмотр каталога 'ls -ld' - то каталог видится
если так же сделать cd - тоже все нормально

если вызывающий аргумент подрихтовать и тильду заменить на нормальный путь /home/$USER
то в функции переходит происходит нормально

Код: Выделить всё

func            '~/PATH_TO_FILE/FILE' - error
func  '/home/$USER/PATH_TO_FILE/FILE' - OK

если просто в терминале набрать переход с тильдой то все нормально:

Код: Выделить всё

cd ~/PATH_TO_FILE/

далее кусок функции и эхо вывод

Код: Выделить всё

#!/bin/sh

func()
{
    SCRIPT=$(basename "$1")
SCRIPT_DIR=$(dirname  "$1")

echo "
'$1'
'$SCRIPT_DIR'
"
# пробовал "оба варианта"
cd   $SCRIPT_DIR
cd   $(dirname  "$1")

...

}

вызов функции

Код: Выделить всё

func            '~/PATH_TO_FILE/FILE' - error
func  '/home/$USER/PATH_TO_FILE/FILE' - OK

...

run_prc.sh: line 80: cd: ~/PATH_TO_FILE: No such file or directory

cd ~/PATH_TO_FILE - OK

...

менять путь - не катит

/bin/bash-3.1.17
/bin/bash-3.2.57
/bin/bash-4.3.30

slackware-12.2

UPDATE вторая часть топика

// run.sh

Код: Выделить всё

#!/bin/sh
clear; set -e

func()
{
echo "ARG1 = $1"
cd    $1
pwd
}

LST=01.lst

while read LINE
do
echo "LINE = $LINE"

ARG=$(echo $LINE | cut -d ' ' -f1)
ARG=${ARG// /}
func $ARG
done < $LST


// 01.lst

Код: Выделить всё

~/tmp  sss


// вывод

Код: Выделить всё

LINE = ~/tmp  sss
ARG1 = ~/tmp
./run.sh: line 7: cd: ~/tmp: No such file or directory
если я ошибаюсь, то поправьте а не критикуйте :о)
Спасибо сказали:

Аватара пользователя
bormant
Сообщения: 1187

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение bormant » 26.10.2015 08:16

Замените одинарные кавычки (') двойными (").

PS. cd '~/PATH_TO_FILE' у вас и в командной строке не сработает, и в сценарии.
Спасибо сказали:

Аватара пользователя
sunjob
Сообщения: 121

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение sunjob » 26.10.2015 10:14

Код: Выделить всё

func            '~/PATH_TO_FILE/FILE' - error
func  '/home/$USER/PATH_TO_FILE/FILE' - OK


тут имелось ввиду не сами команды - а то какой именно параметр передается в функцию...

для полноты я привел во второй части упрощенный код:

Код: Выделить всё

run.sh,  01.lst, вывод

если я ошибаюсь, то поправьте а не критикуйте :о)
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 15823
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение Bizdelnick » 26.10.2015 11:44

Используйте вместо тильды переменную окружения "$HOME".
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
sunjob
Сообщения: 121

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение sunjob » 26.10.2015 12:05

Bizdelnick писал(а):
26.10.2015 11:44
Используйте вместо тильды переменную окружения "$HOME".


то и слону понятно, если, принудительно мануально написать /home/<blah blah blah>/...
то сработает

весь сыр бор был из за того, что
- во первых параметр для функции берется строкой из файла, парсится, берется первое второе третье поле и отправляется в функцию
- во вторых в данном случае намного удобнее пользоваться и писать тильду, чем каждый раз ПОЛНЫЙ путь (т.е. заполнять файл, откуда берутся параметры)

п.с
решение найдено еще вчера, мне надо знать, что скажет думающая часть линуксоидов, неужели никто с подобным не сталкивался и как решали...

п.с.2
я же не здря во второй части привел упрощенный шаблон для понимания что к чему

run.sh, 01.lst, вывод

п.с.3
а если как вы говорите использовать $HOME - и вписать в файл как то
$HOME/tmp sss
то ни чего хорошего не выйдет, прочитается так же косячно как и с тильдой... (опять таки, прежде чем писать, прочитайте внимательно, что написано, вникните, смоделируйте у себя, если уж приведены код и эхо вывод... а уж потом... :о)
ОПЯТЬ ТАКИ АДРЕСУЮ ОБРАТНО К ПРИВЕДЕННОМУ КОДУ - run.sh, 01.lst, вывод (ВТОРАЯ ЧАСТЬ ТОПИКА)
если я ошибаюсь, то поправьте а не критикуйте :о)
Спасибо сказали:

Аватара пользователя
yars
Сообщения: 1144
Статус: Slacker!
ОС: Slackware64-current

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение yars » 26.10.2015 12:11

Тильда как раз и подставляет значение $HOME, вот только для каждого пользователя у этой переменной свое значение. И если скрипт выполняется от имени не того пользователя, как раз и будут возникать ошибки. Пробуйте ~username/path/to/target.
Slackware64-current/Xfce 4.12/Acer TravelMate 5760
-------------
Registered Linux User #557010
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 15823
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение Bizdelnick » 26.10.2015 12:16

Ну тогда не заключайте переменную $1 в кавычки. Но в файле в таком случае нужно будет эскейпить все пробельные символы в пути.
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
yars
Сообщения: 1144
Статус: Slacker!
ОС: Slackware64-current

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение yars » 26.10.2015 12:21

И да, 'одинарные', `обратные` и "двойные" кавычки в bash по-разному себя ведут.
Slackware64-current/Xfce 4.12/Acer TravelMate 5760
-------------
Registered Linux User #557010
Спасибо сказали:

Аватара пользователя
s.xbatob
Сообщения: 807
ОС: Fedora

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение s.xbatob » 26.10.2015 12:29

Насколько я вижу, у вас в функции тильда мало того что quoted, так ещё и результат подстановки значения переменной. Я не знаю, в каком порядке bash производит expansions (если тильда до подстановки переменных - то это ещё одна причина того, что тильда не раскроется), но про кавычки сказано однозначно:
3.5.2 Tilde Expansion

If a word begins with an unquoted tilde character ('~'), all of the characters up to the first unquoted slash (or all characters, if there is no unquoted slash) are considered a TILDE-PREFIX.

Как вы вызывали вашу функцию вы не показали. Похоже, тоже с кавычками
Спасибо сказали:

Аватара пользователя
sunjob
Сообщения: 121

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение sunjob » 26.10.2015 12:54

!!! АЛЕ АЛЕ АЛЕ !!!

ЕЩЕ РАЗ раз привожу ПОЛНЫЙ ЛИСТИНГ-ШАБЛОН БАШ СКРИПТА С ВЫВОДОМ

// run.sh

Код: Выделить всё

#!/bin/sh
clear; set -e

func()
{
echo "ARG1 = $1"
cd    $1
pwd
}

LST=01.lst

while read LINE
do
echo "LINE = $LINE"

ARG=$(echo $LINE | cut -d ' ' -f1)
ARG=${ARG// /}
func $ARG
done < $LST


// 01.lst

Код: Выделить всё

~/tmp  sss


// вывод

Код: Выделить всё

LINE = ~/tmp  sss
ARG1 = ~/tmp
./run.sh: line 7: cd: ~/tmp: No such file or directory


и еще раз говорю, проблема рашена, ИНТЕРЕСУЮСЬ КАК ЭТУ ПРОБЛЕМУ РЕШАЮТ ДРУГИЕ ЛЮДИ
если я ошибаюсь, то поправьте а не критикуйте :о)
Спасибо сказали:

Аватара пользователя
s.xbatob
Сообщения: 807
ОС: Fedora

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение s.xbatob » 26.10.2015 13:24

Если проблема в том, что он не сделал то, что вы хотели - так он и не должен делать это. Я вам попытался объяснить почему.
Спасибо сказали:

Аватара пользователя
SLEDopit
Модератор
Сообщения: 4666
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение SLEDopit » 26.10.2015 13:34

sunjob писал(а):
26.10.2015 12:54
ИНТЕРЕСУЮСЬ КАК ЭТУ ПРОБЛЕМУ РЕШАЮТ ДРУГИЕ ЛЮДИ
Никак. Ну точнее можно, конечно, сделать eval echo $ARG, но eval is evil.
Чуть подробнее поможет понять простой скрипт:

Код: Выделить всё

#!/bin/sh -x
ARG=$(echo '~/tmp')
echo $ARG
ARG=~/tmp
echo $ARG

если его запустить, то получится примерно так:

Код: Выделить всё

 $ ./1.sh
+ echo ~/tmp
+ ARG=~/tmp
+ echo ~/tmp
~/tmp
+ ARG=/home/user/tmp
+ echo /home/user/tmp
/home/user/tmp

иными словами ~ не раскрывается из переменной. Это можно сделать принудительно с помощью eval, но в этом решении очень много минусов.
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:

Аватара пользователя
sunjob
Сообщения: 121

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение sunjob » 26.10.2015 17:17

> но в этом решении очень много минусов
если не сложно, поподробнее
если я ошибаюсь, то поправьте а не критикуйте :о)
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 15823
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение Bizdelnick » 26.10.2015 17:28

sunjob писал(а):
26.10.2015 17:17
если не сложно, поподробнее

Например вместо нормального пути может быть прописано '/какой/то/путь ; rm -rf /'.
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
sunjob
Сообщения: 121

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение sunjob » 26.10.2015 17:57

итак
> Если проблема в том
проблемы ни какой нет

> он не сделал то, что вы хотели
я ни чего не просил сделать...

> Я вам попытался объяснить почему.
то, что вы обьяснили - я в курсе... поэтому и не отвечал

обьясняю, почему я повторно вставил код с шаблоном кода (который был в самом первом сообщении)
- во первых он показывает "боевую проблему" а не обсуждаемые виртуальные проблемы, позволяет полностью смоделировать проблему
- все что говорилось, говорилось не в тему (в контексте, если бы был изучен код скрипта, то подобных советов бы не было)

а теперь подробно,

> Замените одинарные кавычки (') двойными (").
> PS. cd '~/PATH_TO_FILE' у вас и в командной строке не сработает, и в сценарии.
в этом месте я показывал что отправляется в функцию параметром, и что возвращает функция

смотрим внимательно, это дествительно похоже на код баш-скрипта?

Код: Выделить всё

func            '~/PATH_TO_FILE/FILE' - error
func  '/home/$USER/PATH_TO_FILE/FILE' - OK


в данном случае, борман просто сразу ответил, когда я еще не добавил вторую часть сообщения с "тестовым кодом", борману спасибо за быстрый ответ :о)

далее

> Используйте вместо тильды переменную окружения "$HOME"
если бы был изучен код и работа скрипта, то в голову не пришло бы такое советовать, т.к. с подобной переменной произошло бы тоже самое
а именно, смотрим ход действий:
- читаем файл построчно
- разибваем строку (парсим по разделителю) - получаем первый параметр
- убиваем все пробелы
- всем этим сыр-бором - присваиваем значение переменной
- отправляем эту самую переменную параметром в функцию

и что, неужели что то изменится от того что "~/" заменится на "$HOME" в строке читаемого файла?
если, это поможет, то я снимаю шляпу и признаю что был неправ и не прислушался к совету

> Тильда как раз и подставляет значение $HOME, вот только для каждого пользователя у этой переменной свое значение.
> Ну тогда не заключайте переменную $1 в кавычки

аналогично, в данном случае - глупость, применительно к данной проблеме (опять таки, возвращаясь к коду, который я повторно вставил в текст)

> И да, 'одинарные', `обратные` и "двойные" кавычки в bash по-разному себя ведут.

и опять таки к проблеме ни какого отношения не имеет (goto to script)

> Как вы вызывали вашу функцию вы не показали
опять, идем и смотрим код

ИТОГО, у меня ни каких проблем и не поняток...

...

мое решение, вот можете его обсудить, высказать плюсы минусы такого решения

Код: Выделить всё

SCRIPT_DIR=`echo ${SCRIPT_DIR/\~/$HOME}`


если я опять таки в чем то не прав, то поправьте
всем спасибо

### UPDATE ###

> Например вместо нормального пути может быть прописано '/какой/то/путь ; rm -rf /'.

код приведете?
если я ошибаюсь, то поправьте а не критикуйте :о)
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 15823
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение Bizdelnick » 26.10.2015 18:14

sunjob писал(а):
26.10.2015 17:57
если я опять таки в чем то не прав, то поправьте

Вы неправы в том, что раскрытие тильды должно осуществляться только в том случае, если она является первым символом пути. Ваш код работает не так:

Shell

% SCRIPT_DIR=/some/directory~1 % SCRIPT_DIR=`echo ${SCRIPT_DIR/\~/$HOME}` % echo "$SCRIPT_DIR" /some/directory/home/user1 %


sunjob писал(а):
26.10.2015 17:57
код приведете?
Пример уязвимого кода? Любой, в котором используется eval, аргументы (или часть аргументов) которой берутся из левого файла (аргумента командной строки, переменной окружения — нужное подчеркнуть).
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
sunjob
Сообщения: 121

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение sunjob » 26.10.2015 18:37

Код: Выделить всё

/some/directory~1


это че такой за путь? мы в винде че ли? :о)))

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

п.с. все таки пример кода, был бы не плох
если я ошибаюсь, то поправьте а не критикуйте :о)
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 15823
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение Bizdelnick » 26.10.2015 18:43

sunjob писал(а):
26.10.2015 18:37
это че такой за путь? мы в винде че ли? :о)))

Вообще-то в юниксовых именах файлов разрешено использовать любые символы кроме '\0' и '/'.

sunjob писал(а):
26.10.2015 18:37
все таки пример кода, был бы не плох

Ну напишите. Мне некогда.
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
sunjob
Сообщения: 121

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение sunjob » 26.10.2015 18:54

по умолчанию, в том списке, который будет использоваться, тильда будет идти первой, если, естественно, она будет использоваться...

какие еще минусы возможны?
если я ошибаюсь, то поправьте а не критикуйте :о)
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 15823
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение Bizdelnick » 26.10.2015 18:58

Ещё? Не обрабатываются конструкции типа ~username/path, нельзя использовать даже экранированные пробелы в пути. Возможно ещё что-то, я в скрипт не особо вчитывался, как Вы совершенно верно подметили.
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
SLEDopit
Модератор
Сообщения: 4666
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение SLEDopit » 26.10.2015 19:06

sunjob писал(а):
26.10.2015 17:17
если не сложно, поподробнее
здесь всё очень подробно разжёвано.
мне, если честно, немного лениво переводить. поэтому, если с английским не очень, то google translate в помощь.
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:

Аватара пользователя
sunjob
Сообщения: 121

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение sunjob » 26.10.2015 19:10

Код: Выделить всё

SCRIPT_DIR=${SCRIPT_DIR/#\~\//$HOME\/}
SCRIPT_DIR=${SCRIPT_DIR/#\~/$HOME\/}

если я ошибаюсь, то поправьте а не критикуйте :о)
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 15823
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение Bizdelnick » 26.10.2015 19:22

Да, кстати, такие подстановки — это башизмы, так что shebang надо исправить на #!/bin/bash.
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
SLEDopit
Модератор
Сообщения: 4666
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение SLEDopit » 26.10.2015 19:41

sunjob писал(а):
26.10.2015 17:57
мое решение, вот можете его обсудить, высказать плюсы минусы такого решения
по большому счёту вы раскрываете ~ за оболочку. имхо, делать это при чтении файла каким-нибудь sed'ом эффективнее и проще.
и, кстати, делить по переменным можно самим read'ом, что существенно удобнее:

Код: Выделить всё

while read dir file
do
  echo "LINE = $dir $file"
  func $dir$file
done < <(sed 's=^~\([-a-zA-Z0-9_-]\+\)/\?=/home/\1/=;s=^~='$HOME'=;' $LST)

преимущества такого решения:
1. оно раскрывает ~ только в правильном месте + поддерживает ~username
2. оно работает быстрее bash/sh на больших файлах
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:

Аватара пользователя
sunjob
Сообщения: 121

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение sunjob » 26.10.2015 19:43

во, интересный код, будем разбираться, спасибо!


to Bizdelnick
ни чего не надо править :о)

p.s.
надесь поверите на слово
если я ошибаюсь, то поправьте а не критикуйте :о)
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 15823
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение Bizdelnick » 26.10.2015 19:46

sunjob писал(а):
26.10.2015 19:43
ни чего не надо править :о)

p.s.
надесь поверите на слово

Если это мне и про shebang, то Вы неправы. Это может работать в Вашей отдельно взятой системе, если в качестве /bin/sh там используется bash. А например в dash, который вроде бы уже в большинстве дистрибутивов по умолчанию, Вы получите ошибку "Bad substitution".
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
sunjob
Сообщения: 121

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение sunjob » 26.10.2015 19:48

именно если в качестве /bin/sh там используется bash.
если я ошибаюсь, то поправьте а не критикуйте :о)
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 15823
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: bash script - ошибка перехода в каталог с тильдой

Сообщение Bizdelnick » 26.10.2015 19:54

Скрипт никогда не уйдёт за пределы локалхоста, система на котором никогда не будет обновляться?
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали: