Почему Ubuntu не поддерживает команду 'sh example.sh'?

Мой вопрос прост.

Почему ubuntu не поддерживает команду sh example.sh?

В некоторых ситуациях это удобнее, чем cd $wd; ./example.sh и add PATH.

login.sh

~/bin/logmitgw.sh -i 4564646 dfdsfsdf

logmitgw.sh

some code

Когда я бегу sh ~/bin/login.sh

Он печатает

[ 117]

ls -l ~/bin/login.sh

-rwxrwxr-x
-4
задан 18 November 2012 в 08:36

2 ответа

Если скрипт находится в ~ / bin, то ~ / bin уже будет в пути. Пока это bash-скрипт, вы можете запускать его из любого места. Нет необходимости в оболочке, нет необходимости в cd и нет необходимости добавлять что-либо на вашем пути.

Например:

login.sh
0
ответ дан 18 November 2012 в 08:36

Ubuntu поддерживает запуск sh example.sh. Это прекрасно работает, если вы делаете все остальное правильно. Проблема в вашем случае похоже в том, что вы указываете неверный путь к скрипту.


Когда вы открываете терминал в Ubuntu, он, скорее всего, запускает оболочку Bash. Я предполагаю, что это имеет место для вас.

Кроме того, команда sh вызывает другую оболочку:

$ command -v sh
/usr/bin/sh
$ ls -l /usr/bin/sh
lrwxrwxrwx 1 root root 13 Aug  4 11:43 /usr/bin/sh -> /usr/bin/dash

То есть /usr/bin/sh является символической ссылкой на оболочку dash. .В некоторых системах символическая ссылка sh может указывать на другую оболочку.

Одна вещь, которая может пойти не так, это то, что в системе нет sh.

Вот пример скрипта:

$ echo 'echo "works!"' > ~/bin/example.sh
$ sh ~/bin/example.sh
works!

Если я удалю символическую ссылку sh, я получу ошибку:

$ sudo rm /usr/bin/sh
$ sh ~/bin/example.sh
bash: /usr/bin/sh: No such file or directory

Обратите внимание, что это не та ошибка, которую вы получили.

Я запустил sudo ln -s /usr/bin/dash /usr/bin/sh, чтобы снова создать символическую ссылку и вернуть sh.

Еще одна проблема может заключаться в том, что файл не является сценарием оболочки, и dash не может его запустить, или это сценарий оболочки, но он несовместим с dash. В этом случае вы получите какую-то синтаксическую ошибку, например:

$ file /bin/bash
/bin/bash: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=a6cb40078351e05121d46daa768e271846d5cc54, for GNU/Linux 3.2.0, stripped
$ sh /bin/bash
/bin/bash: 1: ELF: not found
/bin/bash: 2: Syntax error: Unterminated quoted string
$ file /usr/bin/uname
/usr/bin/uname: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=3354931bca4ff072b26258a956ffde08ead5f341, for GNU/Linux 3.2.0, stripped
$ sh /usr/bin/uname
/usr/bin/uname: 1: Syntax error: word unexpected (expecting ")")

Но такой ошибки вы не получили.

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

$ ls ~/bin/anything
ls: cannot access '/home/zanna/bin/anything': No such file or directory
$ sh ~/bin/anything
sh: 0: Can't open /home/zanna/bin/anything

0 в этой ошибке — это текущий файл:

$ echo 'echo $0' > ~/bin/something
$ sh ~/bin/something
/home/zanna/bin/something

В своем вопросе вы говорите, что запустили

sh ~/bin/login.sh

и получили

sh: 0: Can't open ~/bin/login.sh

Но эта ошибка не имеет смысла, потому что тильда ~ должна быть расширена до пути вашего домашнего каталога. Запомните мою ошибку:

$ sh ~/bin/anything
sh: 0: Can't open /home/zanna/bin/anything
                     ^___^------expansion of ~    

Я могу воспроизвести вашу ошибку, указав путь:

$ sh ~/bin/example.sh 
works!
$ sh "~/bin/example.sh" 
sh: 0: Can't open ~/bin/example.sh

Может быть, вы так и сделали.

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

sh /bin/login.sh

Это не работает, и будет выведено sh: 0: Не удается открыть /bin /login.sh, если в каталоге верхнего уровня /bin нет файла login.sh. Вы, вероятно, знали бы, если бы создали такой файл, потому что вам пришлось бы сделать это как root.

Еще одна причина появления ошибки sh: 0: Can't open /path/to/file заключается в том, что вы запустили sh ~/bin/login.sh но такого файла не было. Но в этом случае ~ все равно были бы расширены. Кроме того, вы даете первую часть вывода ls -l для вашего файла, чтобы показать разрешения:

-rwxrwxr-x

По-видимому, ~/bin/login.sh — это обычный файл с правами доступа 775. Так что, возможно, проблема была не в этом.

Обратите внимание, что когда вы вызываете интерпретатор, такой как (da)sh, для запуска скрипта, скрипту не обязательно иметь разрешение на выполнение:

$ ls -l ~/bin/example.sh
-rw-rw-r-- 1 zanna zanna 14 Aug  4 11:36 /home/zanna/bin/example.sh
$ sh ~/bin/example.sh 
works!

Но ваш скрипт вызывает другой скрипт, не вызывая интерпретатор для его запуска. Это вызовет ошибку разрешения, если у второго сценария нет разрешения на выполнение:

$ echo '~/bin/example.sh' > ~/bin/something
$ sh ~/bin/something
/home/zanna/bin/something: 1: /home/zanna/bin/example.sh: Permission denied

Но, еще раз, это не та ошибка, которую вы получили.

Вы приняли ответ производителя4, в котором указывалось, что ~/bin добавляется в PATH, если он существует (вы можете увидеть код, который делает это, в ~ /.profile), поэтому, если у вас есть исполняемый файл в ~/bin, вы можете запустить его без указания интерпретатора, но для этого файл должен иметь разрешение на выполнение:

$ example.sh
bash: /home/zanna/bin/example.sh: Permission denied
$ chmod u+x ~/bin/example.sh
$ example.sh
works!

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

Поскольку этот ответ сработал для вас, то кажется что файл существует, имеет разрешение на выполнение и является сценарием, совместимым с Bash.Что пошло не так с вашей попыткой запустить его с синтаксисом sh example.sh, похоже, было то, что вы либо указали путь и предотвратили расширение тильды, либо полностью опустили ~ , таким образом, в любом случае указав неправильный путь к вашему файлу.

2
ответ дан 4 August 2020 в 07:07

Другие вопросы по тегам:

Похожие вопросы: