Является ли ./ (точка косая черта) командой?

16

Суть вопроса:

Вопрос возник, когда я не смог установить программное обеспечение, поэтому я искренне спрашиваю об этом. /, Потому что я не знал об этом, и вывод "команда не найдена" сбивал меня с толку о том, что на самом деле была команда.

Контекст:

Я хотел бы установить файл truecrypt-7.2-setup-x86.

Инструкции говорят, чтобы использовать команду:

sudo ./truecrypt-7.2-setup-x86

Но вывод:

sudo: ./truecrypt-7.2-setup-x86: command not found

ОБНОВЛЕНИЕ: для полноты, в тесте я был в папке с файлом, но еще не сделал исполняемый файл (chmod + x).

ubuntubu
источник
1
./Часть команды говорит «Искать в текущей директории, и выполнить команду„TrueCrypt-7.2-Setup-x86“здесь». Вам нужно запустить эту команду из каталога, куда вы распаковали файл.
Чарльз Грин
2
@Videonauth - Не совсем, лично я не думаю, что это поднимает до уровня ответа.
Чарльз Грин
1
@Zanna Я протестировал сценарий без разрешений на выполнение, и выданная ошибка была ошибкой пропущенного разрешения, а не командой не найдена.
Чарльз Грин
2
@ubuntubu Хорошо, хорошо, вы переехали в каталог - хорошо. Небольшой комментарий по поводу редактирования, хотя. Команда должна быть chmod +x, chmod -xнаоборот - она ​​удаляет исполняемые права
Сергей Колодяжный
4
Название вопроса довольно сильно отличается от основного; может быть, это должно быть исправлено?
Дэвид Z

Ответы:

24

./это не команда. Команда есть ./truecrypt-7.2-setup-x86.

Ваша оболочка и подобные программы sudoбудут обрабатывать команду как путь, если она содержит хотя бы один /символ. Поскольку .представляет любой каталог, в котором вы находитесь в данный момент, ./truecrypt-7.2-setup-x86присваивает имя файлу truecrypt-7.2-setup-x86в текущем каталоге. Если такого файла нет или он не может быть запущен, вы получите сообщение об ошибке.

Когда команда не содержит косой черты, ее $PATHищут в каталогах , как говорит Сергей Колодяжный . Текущий каталог не автоматический поиск - и это не рекомендуется ставить .в $PATH. Таким образом, вы случайно не запускаете вещи, которые не ожидали запустить, потому что вы случайно оказались cdв каталоге, который их содержит.

Письмо ./ перед именем исполняемого файла в текущем каталоге общий способ его запуска, но на самом деле это не специальный синтаксис. Например, если вы испортили свой $PATHи вам нужно было выполнить команду вроде ls, вы можете написать /bin/ls. Нет .необходимости в этом случае или в целом; что-то нужно /где-то в имени пути, чтобы показать, что вы имеете в виду, что это путь.

Поскольку .это всегда текущий каталог и /только разделитель каталогов, первое, что нужно сделать, это проверить, что файл, который вы назвали, действительно существует в текущем каталоге. (Если это так, то проверьте его разрешения , как объясняет Чарльз Грин . Но если вы извлекли файл из архива, у него обычно уже будут права на исполняемый файл, если он предназначен для запуска.)

Элия ​​Каган
источник
21

./ Часть команды говорит: «Посмотрите в текущем каталоге и выполните здесь команду« truecrypt-7.2-setup-x86 »». Вам нужно запустить эту команду из каталога, куда вы распаковали файл.

Это можно проверить: в том же окне терминала, где вы пытаетесь ввести команду, введите команду ls -l true* - если файл присутствует в текущем рабочем каталоге, то отобразится список, показывающий файл (и кучу дополнительной информации).

Как отметила Занна в комментариях, ваш файл может не иметь разрешений на выполнение - это можно легко исправить. В качестве контрольного примера мой каталог показывает

chick@dad:~/test$ ls -l
total 4
-rw-r--r-- 1 chick chick 788 Oct 27 06:15 rFullBack
chick@dad:~/test$

и файл «rFullBack» перечисляет «-rw-» как мое разрешение на чтение и запись файла. Я могу выполнить команду, chmod +x rFullBackи список каталогов изменится на

chick@dad:~/test$ ls -l
total 4
-rwxr-xr-x 1 chick chick 788 Oct 27 06:15 rFullBack
chick@dad:~/test$

Там мои разрешения теперь '-rwx', что означает, что я могу выполнить файл.


Короче говоря, если файл существует в вашем каталоге

запустить команду

chmod +x ./truecrypt-7.2-setup-x86

а затем команда

sudo ./truecrypt-7.2-setup-x86
Чарльз Грин
источник
1
Не совсем. Это перечисляет rw-как ваше разрешение - -прежде чем это для set [gu] id и sticky-битов.
Дункан Х Симпсон
@DuncanXSimpson Спасибо - я немного обновил описание разрешений, но я собираюсь игнорировать биты setguid и sticky для этого ответа!
Чарльз Грин
8

Как работает вызов команд в оболочке

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

Что произойдет, если команда, которую вы хотите выполнить, находится в том же каталоге, где вы сейчас находитесь, но этот каталог отсутствует в списке PATHкаталогов? Вот когда вам нужно использовать ./. Это так же, как делать/bin/bash вы - вы указываете оболочке, где находится желаемая команда, полный путь к ней. А в случае ./ вы говорите, чтобы оболочка "посмотри в этот каталог". Настолько важной частью является то, что вы должны находиться в том же каталоге, где находится файл.

Конечно, для запуска исполняемого файла на нем должен быть установлен исполняемый бит, поэтому вам нужно chmod +x ./my_file .

Итак, важные шаги:

  1. cd где вы сохранили файл; если он есть ~/Downloads, тоcd ~/Downloads
  2. Запустите chmod +x ./truecrypt-7.2-setup-x86, это говорит "сделать файл truecrypt-7.2-setup-x86, который находится в этом каталоге исполняемый файл"
  3. А теперь делай sudo ./truecrypt-7.2-setup-x86

Обратите внимание, что использование ./не является случайным поведением, а фактически является стандартом, определенным стандартом интерфейса переносимой операционной системы (он же POSIX) , в частности, см. Раздел «Поиск и выполнение команд».

Воспроизведение ошибки

$ # my script is in ~/Downloads folder
$ stat -c "%n" /home/xieerqi/Downloads/my_script.sh                         
/home/xieerqi/Downloads/my_script.sh
$ # if I run sudo ./my_script.sh, we get an error
$ sudo ./my_script.sh
[sudo] password for xieerqi: 
sudo: ./my_script.sh: command not found
$ # of course the command not found because file is not in ./, not in this dir
$ # this is not  sudo's problem
$ # but sudo does indeed show the same error even if you're in same directory
$ cd ./Downloads/                                                                                                                                                      
$ sudo ./my_script.sh                                                                                                                                                  
[sudo] password for xieerqi: 
sudo: ./my_script.sh: command not found

ПРИМЕЧАНИЕ : сообщение об ошибке, выданное sudoявно, вводит в заблуждение, поэтому об этом следует помнить; Однако, пожалуйста, обратите внимание, что это не было был суть вопроса, который задает OP.

Документация и ссылки

Из bashруководства по 4.3, раздел «КОМАНДА ИСПОЛНЕНИЯ»:

Если имя не является ни функцией оболочки, ни встроенной функцией и не содержит косых черт, bash ищет в каждом элементе PATH каталог, содержащий исполняемый файл с этим именем.

От чего вам нужно ./ (точка-косая черта) перед именем скрипта, чтобы запустить его в bash? :

Он работает с ./, потому что POSIX указывает, что имя команды, содержащее /, будет использоваться как имя файла напрямую, подавляя поиск в $ PATH. Вы могли бы использовать полный путь для того же эффекта, но ./ короче и проще для написания.

Сергей Колодяжный
источник
На самом деле sudoвывод вводит в заблуждение. Если вы пытаетесь же без sudo, вы получите другую ошибку из bash: Permission denied. И это правильно, поскольку вы не дали сценарию разрешение на выполнение (через chmod +x).
Руслан
@ Руслан факт, что sudoвывод вводит в заблуждение, является правдой, но это ошибка, которая обнаруживается. Это может быть что-то, чтобы сообщить разработчикам и позволить им это исправить. Однако это не является основой обсуждения - нам нужно было выяснить, что сделал OP, чтобы вызвать такую ​​ошибку, и направить их по правильному пути. Является ли это вводящим в заблуждение или нет - это не проблема здесь.
Сергей Колодяжный
С другой стороны, это не совсем то же самое, что использование /bin/bash: он не позволяет вам выполнить скрипт, для которого у вас нет разрешения на выполнение. Когда вы вводите имя сценария предваряющим, все, что имеет значение, это/bin/bash тот факт, что /bin/bashон исполняемый, так как это исполняемая команда. Когда вы этого не делаете, сам скрипт выполняется, что, в свою очередь, приводит к тому, #!что вызывается либо ваша текущая оболочка, либо все, что находится в верхней строке
Монти Хардер,
@MontyHarder /bin/bash- просто пример здесь. Тот факт, что мы звоним /bin/bashи ./script.sh определяем путь к исполняемой вещи - это то же самое. Prefacing script с bash script.shили /bin/bash script.shявляется совершенно другой темой, где вы запускаете исполняемый файл и передаете ему скрипт в качестве аргумента - который, кстати, может сломаться, если синтаксис написан для чего-то другого, кроме оболочки, которую вы вызываете, скажем csh. /bin/bashхорошо исполняемый файл, но дело в том, что вы все еще указываете полный путь к нему.
Сергей Колодяжный
2
@SergiyKolodyazhnyy Префикс имени сценария с помощью /bin/bashили даже просто bashявляется также распространенным способом решения проблемы отсутствия разрешений на выполнение сценария. Указание полного пути к сценарию не решает эту проблему. Так /bin/bashчто это особенно плохой пример в этом конкретном случае.
Монти Хардер