LINUX.ORG.RU

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

 


1

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

~/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
★★★★
Ответ на: комментарий от targitaj

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

а одиночные ковычки тут указаны просто для того, что бы показать, что отправляется в функцию ... слету печатал... в реале вместо PATH_TO_FILE/FILE - используется переменная с «существующим путем, начинаюшимся с тильды»

func '~/PATH_TO_FILE/FILE' - error
func '/home/$USER/PATH_TO_FILE/FILE' - OK
sunjob ★★★★
() автор топика
Ответ на: комментарий от sunjob

// 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

sunjob ★★★★
() автор топика
Ответ на: комментарий от gh0stwizard

если не сложно, посмотрите..

#!/bin/sh
clear; set -e
set expand-tilde on

....

результат тот же

p.s.

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

sunjob ★★★★
() автор топика
#!/bin/sh
func()
{
  script=$(basename "$1")
  SCRIPT_DIR=$(dirname  "$1")

echo -e "$1\n$SCRIPT_DIR"
echo $PWD
cd "${SCRIPT_DIR}"
echo $PWD
}
func ~/123456
./scr.sh 
/home/konstantin/123456
/home/konstantin
/tmp
/home/konstantin
kostik87 ★★★★★
()
Последнее исправление: kostik87 (всего исправлений: 1)

Тильда раскрывается самой первой (до подстановки параметров и раскрытия command substitution).

Вот в этом месте

ARG=$(echo $LINE | cut -d ' ' -f1)

у вас тильда просачивается в значение переменной, как если бы вы написали ARG='~/smth'. После этого она уже не подпадёт под раскрытие тильды т.к. будет появляться в результате подстановки параметров, которая происходит после раскрытия тильд.

Красивого способа починить не знаю. На ум приходят eval ARG=$ARG либо ручной анализ строки.

unterwulf
()
Ответ на: комментарий от unterwulf

Поторопился с указанием места. Нераскрытая тильда попадает в переменную здесь:

while read LINE

unterwulf
()
Ответ на: комментарий от kostik87

причесал ваш код, для более вдумчивого понимания что происходит, все равно код как то странно отрабатывает

#!/bin/bash
clear
# doesn't matter??
set expand-tilde off

f()
{
path=${null:$1}  # tilde hack
cd $path || exit 1
echo "
ARG[1]     = $1
PATH_HACK  = $path
PWD        = `pwd`
"
}

echo -n "### Test 1"
f ~/dev

echo -n "### Test 2 - should fail"
f "~/dev/"

echo -n "### Test 3 - should fail"
ARG="~/dev"
f $ARG

echo -n "### Test 4"
ARG=$(echo -n "~/dev")
f $ARG

вывод

### Test 1
ARG[1]     = /home/sun/dev
PATH_HACK  =
PWD        = /home/sun

### Test 2 - should fail
ARG[1]     = ~/dev/
PATH_HACK  =
PWD        = /home/sun

### Test 3 - should fail
ARG[1]     = ~/dev
PATH_HACK  =
PWD        = /home/sun

### Test 4
ARG[1]     = ~/dev
PATH_HACK  =
PWD        = /home/sun
sunjob ★★★★
() автор топика
Ответ на: комментарий от gh0stwizard

более продвинутое решение

по поводу «более продвинутого решения»... у меня голова взорвалась, пока я пытался разобраться с ним... :о)

решил простым

SCRIPT_DIR=`echo ${SCRIPT_DIR/\~/$HOME}`
sunjob ★★★★
() автор топика
Ответ на: более продвинутое решение от sunjob

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

p.s. принц, зачем вам суженная, возьмите расширенную...(квн, юрмала, девченки из житомира)

sunjob ★★★★
() автор топика
Ответ на: комментарий от gh0stwizard

а вот ДА

а вот за этот код, низкий поклон, реально то, что надо!!!

молодцы, лоровцы!

который раз выручают, без демогогии, быстро и яблочка!

sunjob ★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.