5

I recently moved from windows to linux, and I see one strange thing:

./configure

or

nano /something/something2

Is this something2 a file? It looks like a directory, I don't understand how it can be edited? Same for ./configure. What does it means?

6 Answers 6

20

You're probably confused because these files don't have extensions (endings like .txt), which are essential to determine a file's content on Windows.

On Linux, most programs don't rely on a file's extension to determine which program to open it with, but instead look at its first few bytes (the "magic bytes") that usually reveal the file's type.

Due to that, file extensions can often be omitted and you will encounter lots of README text files and configure scripts.

6
  • 3
    Great interpretation. I didn't think this might be where the confusion is coming in.
    – phemmer
    Commented May 4, 2014 at 0:30
  • 1
    @Patrick I focused on the "something2 looks like a directory" part, which certainly looks like a possible confusion for someone who has only ever seen files with extensions. ;)
    – n.st
    Commented May 4, 2014 at 0:34
  • 1
    I think it would be fair to point to file and libmagic ;) Commented May 4, 2014 at 20:17
  • There was never a time when a Windows/Dos file was required to have an extension or a Windows/DOS directory could not have an extension. Commented May 9, 2014 at 12:54
  • @AdrianPronk I incorrectly assumed that 8.3 filenames required the 3-letter extension to be present, but as it turns out, they've always been optional.
    – n.st
    Commented May 9, 2014 at 16:38
9

Your 2 examples are completely unrelated from each other, and so I'll address them as such.

 

./configure

This is shell notation meaning to execute the file called configure in the current working directory.

Normally when you want to run a program, such as /bin/ls, you just call it as ls. You don't need to specify the path. This works because your shell has a variable called $PATH which has a list of places to search when a non-qualified command is entered. So $PATH would contain /bin, and when you run ls, it looks for it in /bin, and executes it.

Now when you want to run a program which is not in $PATH, you have to qualify that path. If you are currently in /home/johndoe, and you have a program/script called configure in that directory, you can either run it as /home/johndoe/configure or ./configure. Since you're already in that directory, the ./ notation is shorter.

 

nano /something/something2

In this case you're just passing an argument to nano. It doesn't matter more than that.

nano is an editor. So you're just passing /something/something2 as an argument to nano. It is up to nano what it wants to do with that argument. The editor might look at the argument and go "oh, that's a file, lets open it up", or it might go "oh, that's a directory, lets list the contents and let the user pick a file". Or it might throw an error at you :-)

Point is that while nano might intelligently determine what /something/something2 is, it's entirely up to nano. Another editor or program might react completely differently.

10
  • 1
    @WarrenYoung It actually is shell notation. POSIX Command Search and Execution, see the bit about "If the command name contains at least one slash"
    – phemmer
    Commented May 4, 2014 at 0:41
  • hmm, I wouldn't call it a shell notation either. It's just a relative path to the file. The key difference between linux and Windows in this regard is that in Windows, the current directory is always considered first in the PATH w/o actually being listed there. In linux (well bash at least) the current directory isn't in the path unless you explicitly put it there. You can execute a file either by typing it's name if it will be found on the PATH, or by giving the path to that file. The path you type can be absolute (starting w/ /) or relative. Commented May 4, 2014 at 1:24
  • @WarrenYoung I never said you need the shell to invoke a program with / in the name. Where did you get that from? I said that ./ is special shell notation. When you pass a command to the shell that has a / in the name, it does not use $PATH. Here's the source code to prove it: findcmd.c:344 calls absolute_program which is defined at general.c:608.
    – phemmer
    Commented May 4, 2014 at 6:18
  • @WarrenYoung From that same dictionary: "Distinct among others of a kind". A command with a / is treated differently than one without a slash. Thus it is special. :-)
    – phemmer
    Commented May 4, 2014 at 10:09
  • 1
    @orion Absolutely not, that's a security hole.
    – mrr
    Commented May 4, 2014 at 21:50
1

In the unix world there are files, and there are directories. And nothing else. All files are editable, it is up to the user to choose a suitable program.

./configure

There are three parts here, the . which refers to the current directory, the / which separates directories, and configure, which is a file name (has to be, as it does not end with a /.

configure is a unix convention, not a rule. Most software packages contain this script to set up things for the compiler. There are enough minor differences between systems that it has to be done locally. I can type ./configure then make then make install on a lot of standard packages without bothering with the README.

/something/something2

differs from ./something/something2 in that it starts at the top of the filesystem rather than the current directory.

Other things you need to know:

../configure will run (or more commonly not find) the file named configure in the parent directory (two dots)

.configure will run the hidden file (begins with a dot, no slash)

example:

mv this that will rename the file, but it stays in the same folder. if that already exists, it is replaced. There is no "are you sure" question.

mv this ./that is the same

mv this ../that renames and moves the new file up one folder

mv this .that renames the file as before. It's still in the same folder but now has a leading dot, so it disappears from the UI and normal folder listings. mv .that this restores it to visibility.

Warning

rm /something/something2 deletes a single file named something2 in the top-level folder something. If something2 is a directory, it returns an error.

rm -r /something/something2 deletes something2 in the top-level folder something. If something2 is a directory, it deletes the directory and ALL CONTENTS. Again, no "are you sure"

rm -r / something/something2 (note the space) deletes the top-level directory and all contents. In other words, every file on your system. It won't succeed for a number of reasons, but will make a mess of things. When it's done deleting everything, it looks for something/something2 in the current folder (no leading slash) and deletes that as well.

5
  • 1
    "In the unix world there are files, and there are directories. And nothing else." You forgot symlinks, character streams, block devices, virtual filesystems...
    – Luc
    Commented May 4, 2014 at 2:58
  • @Luc symlinks, character devices, block devices are all files. virtual filesystems contain virtual files. Though this argument is a stretch I'll agree. Ethernet devices aren't files :-)
    – phemmer
    Commented May 4, 2014 at 3:22
  • Alright alright, have an upvote then :P
    – Luc
    Commented May 4, 2014 at 3:24
  • Memory swap, attached devices (including ethernet adapters) and the drive itself are treated as files. stdin, /dev/null etc. are kernel constructs but work like files. Everything the user could conceivably want to access is abstracted as a file.
    – paul
    Commented May 4, 2014 at 11:46
  • If you call all of those things files, then directories are files too.
    – mrr
    Commented May 4, 2014 at 21:51
0

I just wrote this as a comment but I think it may also help answer your question for the ./configure part.

There is an important difference between Windows and linux in regards to finding the command to execute.

In Windows, the current directory is always considered first in the PATH w/o actually being listed there.

In linux (well bash at least) the current directory isn't in the PATH unless you explicitly put it there.

When you type a name on the Windows command line such as zip, it first searches the current directory for that command (using some particular rules about extensions to determine what is an executable file that zip may actually refer to), if it finds a matching executable file, it executes it, otherwise it looks through each directory listed in the PATH environment variable.

In the typical linux shell prompt, typing a command works similarly EXCEPT that a name without a path component is only found by looking in the directories listed in the PATH environment variable. In addition as was stated in another answer, linux doesn't care about extensions to identify the type of a file, so if you don't type the extension as part of the name it won't be found, therefore lots of files don't have extensions).

What that means is that in the linux shell if you type configure the path will be searched for an executable file named configure, but unless the current directory is on the path, aconfigure` file in the current directory won't be found and executed.

Since you frequently have files that you want to execute in a directory that isn't on the path, you can run it by giving a path component to it on the command line. Since the . refers to the current directory, you can use the relative path to configure in the current directory by typing ./configure.

If you wanted to run the configure command that was in the build subdirectory of the current directory, you would type build/configure.

You could add the current directory (as .) to your path in linux but it is considered a bad idea, see Is it safe to add . to my PATH? How come?

0

I tend to always use "ls -la" to do directory listings. All the information I need is in the output, the -la means 'list all'

drwxrwxrwx 29 sleepy root      4096 May  4 13:10 .
drwxr-xr-x  8 root   root      4096 Jul 30  2012 ..
drwx------  2 sleepy user      4096 Oct 23  2013 .aptitude
-rwxrwxr-x  1 sleepy user        86 Feb  7 19:55 configure
-rw-rw-r--  1 sleepy user        86 Feb  7 19:55 hello.c
drwx------  5 sleepy user      4096 Jan 21  2013 downloads

from the permissions you can see if it's a directory, because it says 'd'. You can also use the command 'file' to show information of the file or directory, this uses the 'magic' n.st wrote about ... alternatively I use 'tab' completion' after I typed the first letters of a file or directory. So if I type 'cd dow' and hit TAB it completes it to 'cd downloads' only if it's a directory, and if I type 'nano conf' it completes it to 'nano configure' ... Windows Command line has a similar feature.

The . means this directory and .. means one directory up.

Configure has the 'x' executable bit in the permissions and can then be run. But since this directory is not in the default PATH, you have to specify where to find configure, which is in 'this' directory. So ./configure means execute this script in this directory.

If you run nano on a directory it will open nano, but will warn you 'this is a directory' ... for vi it will just show you the directory structure.

There are also hidden files that start with a dot, in my example .aptitude is a file that only shows, because of the 'a' in 'ls -la'

0

Welcome to the Dark Side Mr Janiqua ;-).

Answering your questions one by one:

./configure

What people refer to as "commands" in Linux or UNIX is typically two kind of things:

  • either a shell construct (a builtin, a shell function, an alias),
    etc.
  • or an executable file

To provide you with some context here, what people refer to as shell is typically a program, whose job is to accept some input, and then attempt to interpret that input, and act accordingly after that (execute it if it is an executable, etc).

When you enter some text into a shell, and then press enter, roughly the following happen:

  • The shell tokenizes input, producing lexical tokens corresponding to the input provided. E.g consider that you type gcc hello_world.c into the shell. This will produce the following tokens gcc and hello_world.c
  • After tokenization, the shell will attempt to understand what the first token is (in our case gcc). It will first see if it is a shell construct (a function, an alias, or a builtin) or if it is an absolute path (the location relative to the root directory) to an executable (something like /usr/bin/gcc)
  • If it is neither of the above, the shell will begin to lookup the directories listed in your PATH environment variable, to see if it can find a file with that same name.
  • If it does find it, it usually get's executed[4] with the rest of the tokens passed to it as arguments. If it doesn't, it usually prints an error message like this[5]:

[23:25:59] nlightnfotis@mars : [~] $ lelos bash: lelos: command not found...

Now, you, as a user, usually work in a specific directory tree in the file system, known as your user's home folder, usually denoted as ~. It's common that you, as a user, will actually write a program, or a shell script (a sequence of shell commands to be processed non-interactively).

Now, assuming you write a c program, and compile it to a hello executable, you have two ways of executing it. The first one is moving or copying it to a directory that is in $PATH (or adding the current folder to $PATH, but for security reasons that's not a good idea) or executing it right from the folder you are. To do the latter, you use the dot slash (./) to precede commands that you want the shell to execute, and lookup in the folder that you currently are in.

nano /something/something2

Is this something2 a file? It looks like a directory, I don't understand how it can be edited? Same for ./configure. What does it means?

In the UNIX world, the universal abstraction over everything is that of a file. What this means is that everything (or nearly everything for that matter), even if it is an image, a text file or even a device, is generally able to be read() or write() by any program that wishes to do so. As far as the operating system is concerned, it can be anything, but to the userspace application it will be presented as a sequence of bytes that is up to the application to choose how to present or manipulate.

A good first way to understand what something is, is by using the ls command, using the -l flag too. This will produce output that is similar to this:

[23:38:58] nlightnfotis@mars : [~] $ ls -l
-rw-r--r--.  1 nlightnfotis nlightnfotis 280906037 Jan 24 16:30 OpenSPARCT2.1.3.tar.bz2
drwxrwxr-x.  4 nlightnfotis nlightnfotis      4096 Jan 11 16:53 opt

Doing so will present you with several columns, with the first one corresponding to the permisions, the second one being the number of hardlinks, the third one being the file owner, the fourth being the file group, next one is the file size, followed by the modification time and last, but not least the filename.

To easily understand if something is a directory, you will notice the first letter in its permissions to be d. That signals that object to be a directory.

If you still see a file, and are unsure about its nature, you can use a userspace utility called file, that attempts to classify a file based on what is known as its magic number, usually some bytes stored at or near the beginning. For instance running file on that bzip2 file results in:

[23:45:54] nlightnfotis@mars : [~] $ file OpenSPARCT2.1.3.tar.bz2 
OpenSPARCT2.1.3.tar.bz2: bzip2 compressed data, block size = 900k

For a text file, the output is similar to this:

[23:45:57] nlightnfotis@mars : [~] $ file report
report: ASCII text

Feel free to experiment with file and different kind of files.

Now, to answer specifically to your

I don't understand how it can be edited?

question, the answer is very simple. As I mentioned earlier, everything is a sequence of bytes. You just change those bytes.

If it is a text file, you open it with a text editor, change a letter and then save. This corresponds to your text editor finding the offset in the file where that character is located, and change its bytes, to the bytes that represent the new character.

As far as binary (i.e not text) files are concerned, the answer is pretty simple: Again you use some kind of software, either a piece of software that is designed specifically to handle that type of file, or you just use a hex editor (or just a plain text editor) to edit it. For instance, you can use vim, a text editor, to edit a binary, such as python like this: vim /usr/bin/python. It will result in a screen like this:

Python in vim

The many weird characters in there, are just plain bytes that lack a representable character in ASCII. To enter hex view in vim, just type while inside it :%!xxd. You will be presented with a screen like this:

Vim in hex

Then proceed to edit the file, save (:wq), and then exit hex view by typing :%!xxd -r. Just be careful not to trash an important binary while experimenting, or do your experiments inside a virtual machine and you are all good.

Another useful tool you can use to view the bytes of any file is hexdump. In fact, do try to create empty files or files with only a few characters, hexdump -C them, and checkout the output and the ASCII table for a moment of enlightenment :)

If you want to see the (assembly) code that corresponds to those bytes (when we are talking about an executable), you can also use another tool, called objdump to inspect them, likewise objdump -d /usr/bin/python. In my screen it produces like this:

Objdump python

Hope all this was useful, and may the source be with you :)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Footnotes:

[4] The specific mechanisms behind that involve two UNIX system calls known as fork() and exec(). In code, the shell fork()s itself to create a child process, which then proceeds to call exec() with the first token as the first argument, to replace it's core image (the code) with the binary that it exec()'s to.

Working code for that is the following (dumped down a little bit to be as simple as possible):

pid = fork(); // pid is the process id returned by `fork()`
if(pid == 0) // in the child process, pid is zero
  exec(argv[0], argv[1]); // if we are the child process, execute the argument that was given

[5] Okay, that whole shell explanation was a little bit simplistic, as there are more things that the shell does, like parsing for instance, because the command given to it might be more than just a simple executable with some arguments, and include redirections of output, pipes, etc that follow special courses of action, but still the overall description of what the shell does is pretty accurate. For a small and working shell, check out xv6's shell implementation

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .