LINUX.ORG.RU

bash vs sh: моя запутаться

 ,


0

1

есть некий код
пробуем запускать

sh use deadbeef ololo
old: media-sound/deadbeef ape converter dts hotkeys psf src supereq alac curl shellexec cover cover-imlib2 mms lastfm wma zip pltbrowser m3u
new: /deadbeef ololo 
аха - тыква
запускаем иначе
./use deadbeef ololo
old: media-sound/deadbeef ape converter dts hotkeys psf src supereq alac curl shellexec cover cover-imlib2 mms lastfm wma zip pltbrowser m3u
new: media-sound/deadbeef ape converter dts hotkeys psf src supereq alac curl shellexec cover cover-imlib2 mms lastfm wma zip pltbrowser m3u ololo
ладушки
но!
ls -lh /bin/sh 
lrwxrwxrwx 1 root 0 4 янв 24 06:00 /bin/sh -> bash
и
sh --version
GNU bash, version 4.2.45(1)-release (i686-pc-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
спотыкается на вот этом коде
find_category(){
	source "/etc/make.conf" 2>/dev/null
	source "${PORT_ETC}/make.conf" 2>/dev/null
	[[ -z "${PORTDIR}" ]] && PORTDIR="/usr/portage"
	if [[ -n "$(eix -V 2>/dev/null)" ]];then
		PORTDIR_OVERLAY="$(eix --print PORTDIR_OVERLAY)"
	else
		export "$(grep "^PORTDIR_OVERLAY=" <<< "$(emerge --info 2>/dev/null)" | tr -d \")"
	fi
	for target in ${PORTDIR} ${PORTDIR_OVERLAY};do
		categories+="$(ls -d1 ${target}/{*-*,virtual} 2>/dev/null)"$'\n'
	done
	categories="$(sed '/^$/d' <<< "${categories}" 2>/dev/null)"
	while read line;do
		if [[ -d "${line}/${atom}" ]];then
			category+="${line##*/}"$'\n'
		fi
	done <<< "${categories}"
	echo "${category}"
}
скрин
какого!?

★★★★

Последнее исправление: megabaks (всего исправлений: 1)

Ответ на: комментарий от hizel

малыш, по делу сказать есть что?
нет? так иди и дальше уродуй лор.

megabaks ★★★★
() автор топика
Последнее исправление: megabaks (всего исправлений: 1)

(Пальцем в небо) баш видит, что его запустили под именем ш, и он запускается в каком-либо режиме совместимости.

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

до этого я уже догадался, интересно где именно он спотыкается.
есть у меня скриптик в 1800+ строк, в котором используются вроде как все конструкции из кода в ОП, но он таким не страдает

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

bash трам-пам-пам работает - это понятно
выхлопы

[ megabaks@desktop ] ~ $ sh portopts/test deadbeef ololo
[ megabaks@desktop ] ~ $ bash portopts/test deadbeef ololo
media-sound

[ megabaks@desktop ] ~ $ 

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

до этого я уже догадался, интересно где именно он спотыкается.

	done <<< "${categories}"

Это чисто башевская конструкция.

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от megabaks

Хмм, я запустил тоже, такая же фигня

Причем, оно валится сразу же после первого source

user@meowr /tmp $ sh test.sh 
waat
test.sh: line 5: /etc/make.conf: Нет такого файла или каталога
user@meowr /tmp $ cat test.sh 
target=bash

find_category(){
echo waat
        source "/etc/make.conf"
echo wat

Видимо, в sh так нужно. При этом set +x не влияет

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

Т.е. если вот так сделать, то все работает:

        if [ -f "/etc/make.conf" ]; then
                source "/etc/make.conf"
        elif [ -f "${PORT_ETC}/make.conf" ]; then
                source "${PORT_ETC}/make.conf"
        fi
derlafff ★★★★★
()
Ответ на: комментарий от megabaks

и при этом он нормально овер sh отрабатывает

тестить скрипты на баше в режиме совместимости почти бесполезно

для этих целей больше подходит dash, ибо он больше на настоящий sh похож и не позволяет башизмов

$ read lol <<< lol
sh: 2: Syntax error: redirection unexpected
$ 
derlafff ★★★★★
()
Ответ на: комментарий от derlafff

бинго!
сраный sh спотыкается именно на этом.
а bash молодец.
оставлю на всякий случай костыль.
решено.

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

ставить сие не имеет смысла.
а перепиливать под sh тем более глупо - в том же portconf 151 раз используется <<< - всё это перепиливать на костыли совместимости не имеет смысла, тем более что в генте bash есть всегда - таки часть портажа на нём

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

почему-бы тебе явно не написать #!/bin/bash в самом начале? Причём это /bin/bash должно указывать именно на bash. Вот так:

$ file /bin/bash
/bin/bash: ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), stripped
(естественно в твоём дистре путь может быть другим)

Тогда неоднозначностей не будет, и ОС будет точно знать, чем ей пользоваться. Можно и ключей напихать.

#!/bin/bash --posix

echo $POSIXLY_CORRECT

скажет «y».

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

почему-бы тебе явно не написать

это и написано - если ты внимательно читал, то должен был заметить, что ./ололо работает как надо

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

дык в чём твоя проблема?

If bash is invoked with the name sh, it tries to mimic the startup behavior of historical versions of sh as closely as possible, while conforming to the POSIX standard as well.

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

а перепиливать под sh

и тут до Штирлица начало что-то доходить

тем более глупо - в том же portconf 151 раз используется <<< - всё это перепиливать на костыли

а, не, ложная тревога

в генте bash есть всегда - таки часть портажа на нём

Шта!? Это дискриминация! Пойду, прибью bash у себя в уютненькой!

hizel ★★★★★
()
Ответ на: комментарий от Xenesz

Он не о симлинке догадывается, а знает, по какой команде он был запущен.

Black_Shadow ★★★★★
()
Ответ на: комментарий от Xenesz

Баш догадывается, что его вызвали не по имени, а по симлинку? Srsly?

Да. Нулевой аргумент /bin/sh, а не /bin/bash и баш меняет поведение. Это обычная практика. Например все команды LVM, это линки на один бинарник /sbin/lvm

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

Про нулевой аргумент забыл, прошу прощения.

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

Баш догадывается, что его вызвали не по имени, а по симлинку? Srsly?

оно читает argv[0], там как раз имя записано.

Вот ещё примеры:

swapoff -> swapon

umount -> ../bin/umount

reboot -> halt
poweroff -> halt
emulek
()
Ответ на: комментарий от sdio

Например все команды LVM

ещё busybox эпичный пример.

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