0

In Linux, there are 7 file types: (ref - https://en.wikipedia.org/wiki/Unix_file_types)

  1. Regular file
  2. Directory
  3. Block (buffered) file
  4. Character (unbuffered) file
  5. Pipe (named pipe, FIFO) file
  6. Symbolic link to a file or directory
  7. Socket file

( * For the symbolic link type, it can be linked to all seven types.)

In the basic way, regular file and symbolic link to a file can be sourced and called as a program.

. regular_file_script.sh
regular_file_program
. symlink_to_regular_file_script.sh
symlink_to_regular_file_program

As far as I know, directory and symbolic link to a directory cannot be used as a sourced script or be called as a program.

Recently I find that it is possible to use a pipe file as a sourced script. You can create a pipe file and write a script to it, and then source it in another terminal. Here's an example:

In terminal A:

$ mkfifo /tmp/pipe_script.sh ; echo 'echo i am a pipe_script' > /tmp/pipe_script.sh

In terminal B:

$ cat /tmp/test.sh
#!/bin/sh

echo sourcing a pipe script
. /tmp/pipe_script.sh
echo complete

$ /tmp/test.sh
sourcing a pipe script
i am a pipe_script
complete

However, I find that a pipe file cannot be directly called as a program. Even if the permissions are set to 755, it will result in a Permission denied error. For example:

In terminal A:

$ mkfifo --mode 755 /tmp/pipe_program ; echo 'echo i am the pipe_program' > /tmp/pipe_program

In terminal B:

$ cat /tmp/test.sh
#!/bin/sh

# echo sourcing a pipe script
# . /tmp/pipe_script.sh
echo call a pipe program
/tmp/pipe_program
echo complete

$ /tmp/test.sh
call a pipe program
/tmp/test.sh: line 6: /tmp/pipe_program: Permission denied
complete

Why a named pipe file can be sourced, but not called as a program?

All in all, among the seven types, which types of Linux files can be sourced as a script or called as a program?

2
  • So, you've never seen a programming project website encourage visitors to do this: curl https://example.com/path/to/installer.sh | bash.
    – Kaz
    Commented Dec 25, 2023 at 19:42
  • lukespademan.com/blog/the-dangers-of-curlbash
    – Kaz
    Commented Dec 25, 2023 at 19:42

3 Answers 3

0

Anything can be source'ed as long as BASH is able to read it, even the device file (if permissions are right).

"Program" is a whole different issue, and I've not heard of anything other than plain files which can called be this name.

Symbolic links are rarely if ever used for running applications. A normal Linux system contains a ton of hard links for applications but symlinks are usually reserved for shared libraries. Hard links are indistinguishable from normal files, they share everything including permissions.

7
  • Debian's alternative system is based on symlinks, so on many Debian systems symbolic links are frequently used for running applications. Commented Dec 25, 2023 at 16:23
  • Debian is not the only distro to make use of /etc/alternatives and "frequently" is not the word I'd use. In fact alternatives covers maybe 3% of binaries on a given system. Commented Dec 25, 2023 at 16:37
  • 1
    @Henriksupportsthecommunity It may be nit-picky but I would not say that a symlink can be called as a program. When you try to execute a symlink, the link is dereferenced repeatedly until you get to the final target. If this target is a block device or a pipe, the execution will fail. If the target is on a partition mounted -noexec, you'll get a different error even if the symlink is on a partition that allows for execution. One additional point is that the symlink's perms are usually 0777, indicating an executable but the actually perms are that of the target.
    – doneal24
    Commented Dec 25, 2023 at 19:29
  • 1
    @ArtemS.Tashkinov, you didn't write that symlinks are not run, but that they're rarely used for running. These are 2 different things. You might think to clarify.
    – stoney
    Commented Dec 26, 2023 at 8:55
  • 1
    As for the relative frequency of hard and symlinks to executables, I have 63 hard links in /bin, /usr/bin, /sbin, and /usr/sbin (on a non-/usr-merged Debian system), and 1539 symbolic links, of which only 328 are links to /etc/alternatives. There are 7752 executables (of any type) all told in these directories. Commented Dec 27, 2023 at 13:25
0

As others have said, anything that can be read can be sourced by a shell, or piped into a shell. This also works with some other interpreters, e.g. Python.

The Linux kernel however will only run paths which resolve to a regular file, optionally after resolving symbolic links. This is indirectly documented in man execve, which indicates that EACCES (the “permission denied” error you saw) is returned if

The file or a script interpreter is not a regular file.

execve resolves symbolic links, but other similar system calls can be configured to return an error instead; see man execveat and AT_SYMLINK_NOFOLLOW.

You can see the last-chance explicit check for regular files in do_open_execat in the kernel:

    /*
     * may_open() has already checked for this, so it should be
     * impossible to trip now. But we need to be extra cautious
     * and check again at the very end too.
     */
    err = -EACCES;
    if (WARN_ON_ONCE(!S_ISREG(file_inode(file)->i_mode) ||
             path_noexec(&file->f_path)))
        goto exit;
0

The most obvious reason you cannot run a pipe as an executable is that it doesn't support random access.

Executing a file involves:

  1. The kernel opens the file, and reads a few bytes of the header.
  2. Based on the header bytes, it decides what type of executable it is and dispatches the correct binary format module to further handle the program.
  3. Ultimately, the executable is handled to a user-space interpreter, which wants to open the file again, and read the entire header.

An interpreter cannot open the file again and read the same content, if the file is a FIFO. Each time you open a FIFO for reading, a rendezvous takes place with a writer which has the FIFO open for writing. A new pipe object is created which is then used for those two processes to communicate.

You must log in to answer this question.

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