Is ./ (dot slash) a command?

7,391

Solution 1

./ is not a command. The command is ./truecrypt-7.2-setup-x86.

Your shell and programs like sudo will treat a command as a pathname when it contains at least one / character. Since . represents whatever directory you are currently in, ./truecrypt-7.2-setup-x86 names the file truecrypt-7.2-setup-x86 in the current directory. If there is no such file, or there is but the file cannot be run, then you will get an error message.

When a command does not contain a slash, the directories listed in $PATH are searched for it, as Sergiy Kolodyazhnyy says. The current directory is not automatically searched--and it is not recommended to put . in $PATH. That way, you don't accidentally run things you didn't expect to run because you happened to have cdd to a directory that contains them.

Writing ./ before the name of an executable in the current directory the common way to run it, but this is not actually a special syntax. For example, if you messed up your $PATH and you needed to run a command like ls, you could write /bin/ls. No . is necessary in that case or in general; what's needed is a / somewhere in the pathname to signify that you mean it is a pathname.

Since . is always the current directory and / is just the directory separator, the first thing to do is check that the file you've named really exists in the current directory. (If it does, then check its permissions, as Charles Green explains. But if you extracted the file from an archive, then it usually will already have executable permissions if it is intended to be run.)

Solution 2

The ./ part of the command is saying "Look in the current directory, and execute the command 'truecrypt-7.2-setup-x86' from here". You need to run this command from the directory where you unpacked the file.

This can be tested: In the same terminal window where you are trying the command, enter the command ls -l true* - if the file is present in the current working directory, then a listing showing the file (and a bunch of additional information) will be displayed.

As Zanna has noted in the comments, your file may not have execute permissions - this can be fixed easily. As a test case, my directory shows

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

and the file "rFullBack" lists '-rw-' as my permission, to read and write the file. I can execute the command chmod +x rFullBack and the directory listing changes to

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

There my permissions are now '-rwx', indicating I can execute the file.


In short, if the file exists in your directory

run the command

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

and then the command

sudo ./truecrypt-7.2-setup-x86

Solution 3

How does calling commands in shell work

No, it is not a command. The way shells work is when you type in a line of text, first word is going to be treated as command, and if the command is not one of the shell built-in ones then the shell will look at all locations listed in PATH environment variable.

What happens if when the command you want to run is in the same directory as you currently located but that directory isn't on the list of PATH directories ? That's when you need to use ./. It is in a way exactly the same as doing /bin/bash - you are telling the shell where your desired command located, a full path to it. And in case of ./ you're saying to shell "look in this directory". So important part is that you have to be in the same directory where the file is located.

Of course, in order to actually run an executable, it must have executable bit set, so you'll need to chmod +x ./my_file.

So the important steps:

  1. cd where you saved the file; if it's in ~/Downloads, then cd ~/Downloads
  2. Run chmod +x ./truecrypt-7.2-setup-x86 , this says "make file truecrypt-7.2-setup-x86 that is in this directory executable"
  3. And now do sudo ./truecrypt-7.2-setup-x86

Note that use of ./ is not random behavior, but actually is a standard, specified by Portable Operating System Interface standard ( aka POSIX ), specifically see "Command Search and Execution" section.

Reproducing the error

$ # 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

NOTE: the error message given by sudo is obviously misleading so this is something to be kept in mind; however please note that this wasn't the core of the question that OP is asking.

Documentation and references

From bash 4.3 manual, "COMMAND EXECUTION" section:

If the name is neither a shell function nor a builtin, and contains no slashes, bash searches each element of the PATH for a directory containing an executable file by that name.

From Why do you need ./ (dot-slash) before script name to run it in bash?:

It works with ./ because POSIX specifies that a command name that contain a / will be used as a filename directly, suppressing a search in $PATH. You could have used full path for the exact same effect, but ./ is shorter and easier to write.

Share:
7,391

Related videos on Youtube

ubuntubu
Author by

ubuntubu

Updated on September 18, 2022

Comments

  • ubuntubu
    ubuntubu over 1 year

    Core of the question:

    The question arose while I could not install the software, so I am genuinely asking about ./ because I didn't know about it and the output "command not found" was confusing me about what actually the command was.

    Context:

    I would like to install the file truecrypt-7.2-setup-x86.

    Instructions say to use the command:

    sudo ./truecrypt-7.2-setup-x86
    

    But the output is:

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

    UPDATE: for completeness, in the test I was in the file folder but had not yet made the file executable (chmod +x).

    • Admin
      Admin over 6 years
      The ./ part of the command is saying "Look in the current directory, and execute the command 'truecrypt-7.2-setup-x86' from here". You need to run this command from the directory where you unpacked the file.
    • Admin
      Admin over 6 years
      @CharlesGreen dont you want to put that as an answer?
    • Admin
      Admin over 6 years
      @Videonauth - Not really, personally I don't think it raises to the level of an answer.
    • Admin
      Admin over 6 years
      @Zanna I tested a script without execute permissions, and the error thrown was a missing permission error, not a command not found.
    • Admin
      Admin over 6 years
      @CharlesGreen it's only with sudo I get the command not found error when there's no execute permission
    • Admin
      Admin over 6 years
      I didn't try that! I learn a little more every day it seems... ☺
    • Admin
      Admin over 6 years
      That error could appear because OP didn't cd into directory where file is located and is blindly following instructions. cd ~/Downloads first or wherever you saved it.
    • Admin
      Admin over 6 years
      @sergiy, I had moved to the file directory before executing, updating the question
    • Admin
      Admin over 6 years
      @ubuntubu OK, very well, you've moved into the directory - good. Small comment on the edit, though. The command should be chmod +x, the chmod -x is the opposite - it removes executable permissions
    • Admin
      Admin over 6 years
      @Zanna did you see my answer ? I reproduced the error
    • Admin
      Admin over 6 years
      The question title is quite different from the body; maybe that should be fixed?
    • Admin
      Admin over 6 years
      The title is confusing cause of the sans-serif font. I thought it was a typo of ls ./ -a.
    • Admin
      Admin over 6 years
      @wjandrea no, what David is talking about is the fact that in the title OP asks about ./ , but their issue primarily is that they can't install desired software by following instructions which involve using ./. That's why it confusing to some people
    • Admin
      Admin over 6 years
      @SergiyKolodyazhnyy Oh, I wasn't responding to David.
    • Admin
      Admin over 6 years
      @ Sergiy , yes, the question raised while I could not install the software, so I was genuinely asking about ./ because I didn't know about it and the output "command not found" was confusing me about what actually the command was. I find very interesting the variety of the information in the answers and the way people structured their answers.
    • Admin
      Admin over 6 years
      I don't have the reputation to comment, so I'm posting this as an 'answer'. You want to use VeraCrypt, rather than TrueCrypt, since the latter (AFAIK) is no longer well maintained.
    • Admin
      Admin over 6 years
      @ubuntubu can you please add that to your question body ? Explaining that you actually asking about ./ and give information about truecrypt as merely context for the question - all that will prevent confusion. And really, it's a great question and important one for people to understand how things work in shell.
  • Iluvathar
    Iluvathar over 6 years
    Actually sudo output is misleading. If you try the same without sudo, you'll get another error from bash: Permission denied. And rightfully so, since you've not given the script permission to execute (via chmod +x).
  • Sergiy Kolodyazhnyy
    Sergiy Kolodyazhnyy over 6 years
    @Ruslan the fact that sudo output is misleading is true, but that's the error that shows up. That might be something to report to developers and let them fix it. This isn't the core of the discussion however - we needed to establish what OP has done to produce such error, and guide them to the right path. Whether or not it's misleading - that's not the issue here.
  • Monty Harder
    Monty Harder over 6 years
    In another way, it's not exactly the same as using /bin/bash: It does not allow you to execute a script on which you don't have execute permission. When you preface the script name with /bin/bash, the fact that /bin/bash is executable is all that matters, as it is the command being executed. When you don't do that, the script itself is being executed, which in turn leads to either your current shell or whatever's on the top #! line being invoked
  • Sergiy Kolodyazhnyy
    Sergiy Kolodyazhnyy over 6 years
    @MontyHarder /bin/bash is merely an example here. The fact that we're calling /bin/bash and ./script.sh by specifying the path to thing being executed - that's the same. Prefacing script with bash script.sh or /bin/bash script.sh is entirely different topic, where you run an executable and pass script to it as argument - which by the way can break if syntax is written for something other than the shell you're calling , say csh. /bin/bash is executable alright, but the fact is that you're still specifying full path to it.
  • Dessa Simpson
    Dessa Simpson over 6 years
    Not quite. It lists rw- as your permission - the - before it is for set[gu]id and sticky bits.
  • Monty Harder
    Monty Harder over 6 years
    @SergiyKolodyazhnyy Prefacing a script name with /bin/bash or even just bash is also a common way to solve the lack of executable permissions on the script. Specifying the full script path does not solve that problem. So /bin/bash is a particularly bad example in this specific case.
  • Sergiy Kolodyazhnyy
    Sergiy Kolodyazhnyy over 6 years
    @MontyHarder prefacing name with bash should only be done in two cases - 1) you're 100% sure it's bash-compatible, and 2) you know the script doesn't contain anything malicious. It's not solution to "permission issue" , it's opening door wide open to malware. If it's compiled binary and not a script bash binary won't work. That's one thing. Another things, please re-read my answer. I stated clearly that one must use chmod +x to give executable permissions to file/script. And again, /bin/bash vs. ./ is to explain how shell works. You clearly missed the point in the answer
  • Charles Green
    Charles Green over 6 years
    @DuncanXSimpson Thanks - I updated a little the description of the permissions, but I'm going to ignore the setguid and sticky bits for this answer!
  • Thomas Ward
    Thomas Ward over 6 years
    @SergiyKolodyazhnyy On the question of whether or not the sudo output is misleading: it's valid that it is misleading, and you should probably consider making a note that running a given script requires it to have an executable bit if you are running it alone. (But to be wary running any kind of installer or script this way without knowing what it does)
  • Thomas Ward
    Thomas Ward over 6 years
    @MontyHarder as was stated, prefacing with /bin/bash should ONLY be done if you know it's a Bash script being executed. In the question from the OP, it focuses on whether ./ is a command or not (it's not), and is specifically about whether the truecrypt installation executable is able to be executed or not. Therefore, the standard of "You need to set it as executable" is the core issue there.