3

A coworker recently asked "What is man"? After being informed that not all things accessible from the Bash CLI are commands, I was wary to call man a command.

man man just calls it an interface:

NAME
       man - an interface to the on-line reference manuals

man has an executable:

$ which man
/usr/bin/man
$ file /usr/bin/man
/usr/bin/man: ELF 64-bit LSB shared object

So is man a program, because it has an executable? What other nouns could man be? What noun would best describe it? Really, I'm interested in the general case of how I could determine what an arbitrary thing on the cli is, man is just an example.

For that matter, what is the word for all things that one could use on the Bash CLI? A word that encompasses commands, aliases, system calls, etc?

10
  • 2
    Bash has a shell built-in type ..., which tells you where external commands are, and the type of anything else it recognises. type alias man fi type for example. Commented Jun 9, 2022 at 8:51
  • 2
    Is your question answered by Are they commands or utilities?
    – Kusalananda
    Commented Jun 9, 2022 at 8:53
  • 1
    I'm not sure how the creat() example aligns here, since it's not something you can directly call from a shell command line. (Of course pretty much any program might use it, same as a shell redirection like > somefile, though then again creat() is redundant, as you might as well call open() with the appropriate flags, but in any case, you don't make system calls by name from the shell command line)
    – ilkkachu
    Commented Jun 9, 2022 at 12:30
  • 2
    @ilkkachu with a little help from ctypes.sh ... ;-) Commented Jun 9, 2022 at 12:34
  • 1
    @StephenKitt, nggg... oh deary. Let's try keep that away from any children, please... I do like how they've included the "Here is what people have been saying about ctypes.sh" section there. I like what they've included there. Yes, that sounds like something that might make mortal men lose their sanity.
    – ilkkachu
    Commented Jun 9, 2022 at 12:45

3 Answers 3

9

In POSIX terms, anything that can ask the shell to do something is a command:

A directive to the shell to perform a particular task.

So

man man

is a command, as is (technically)

man

man is also a utility:

A program, excluding special built-in utilities provided as part of the Shell Command Language, that can be called by name from a shell to perform a specific task, or related set of tasks.

(The exclusion isn’t significant here; it’s mentioned because special built-in utilities have specific properties.)

To find out what a given command is, use type. This will tell you if it’s built-in, or a program on the PATH (and where), or an alias etc. (or unknown).

Note that system calls aren’t usable as shell commands.

See also Are they commands or utilities? and What is the difference between a builtin command and one that is not?

0
5

Starting from the lowest level:

System calls

System calls are the way userland tasks (must) use to request some service from the kernel and run into priviledged kernel mode.

Let's say for example C is your programming language and you want your task to change its current directory, you will need to insert a chdir() instruction into your program.

Of course these procedures are not immediately accessible from the command line. v.g. typing chdir on the command line won't call the chdir system call.

The list of all available system calls is of course kernel dependent and the only reliable source is certainly the include/linux/syscalls.h header file of your kernel source distribution.

Instructions

A CLI is an interface to the task you are running. Whatever you type in is called an instruction simply because it it supposed to instruct the task to achieve some action.

Commands

What you type will first make its way through an interpreter that will perform some lexical analysis on the tokens you typed and, in the particular case of a shell, might recognize the name of a command (understood as not a variable assignment) and incidentally decide that it needs to resort to another program in order to achieve your request. It will then fork a child process that will exec the binary of that other program.

But there are special cases for which the task might find easier to satisfy the request without resorting to external programs (trivial calculus for instance) or, more important, must execute your request internally.

Built-in commands

Coming back to our initial will to change the active directory, the user will issue the well known shell command cd. What the user actually wants is to get the current directory of his shell to be changed. And because the chdir system call only changes the current working directory of the caller, the shell just cannot fork another process that would not change anything for its parent. The shell must execute the chdir system call internally.

The shell built-in commands are listed in all yourshellname man pages.

Aliases

Aliases are nothing else than synonyms that any user can setup and that will be translated by the command line interpreter into the desired string (supposed to represent whatever legal instruction to the shell.)

The list of all currently active aliases can be obtained thanks to the shell built-in alias command.

3
  • I must say instruction is more commonly tied to "machine instructions" or "assembly instructions" in the field of computers. Better substitutes include statement and directive.
    – iBug
    Commented Jun 10, 2022 at 20:39
  • @iBug : For having a long time programmed in assembly language, I would like to agree with you. However, strictly speaking, according to sh and bash manuals, these programs are defined as "command line interpretors". You enter "commands" composed of "command names" and "operands". But, in the context of a programming language I find hard to call some variable assignment a "command". And even more "then" "else"… that are nothing but keywords. But, let's go with your suggestion of "directive". That can indeed fit for all. I'll modify my contribution.
    – MC68020
    Commented Jun 10, 2022 at 22:20
  • If you're going to mention system calls you surely need at least mention library calls. getpwent(3) vs open(2), read(2), close(2) Commented Jun 15, 2022 at 6:37
4

I have a small shellscript, that can help me identify a command: what kind of command it is and if installed via a program package, which package. Maybe use the name what-about,

#!/bin/bash

LANG=C
inversvid="\0033[7m"
resetvid="\0033[0m"

if [ $# -ne 1 ]
then
 echo "Usage: ${0##*/} <program-name>"
 echo "Will try to find corresponding package"
 echo "and tell what kind of program it is"
 exit 1
fi
command="$1"

str=;for ((i=1;i<=$(tput cols);i++)) do str="-$str";done
tmp="$command"
first=true
curdir="$(pwd)"
tmq=$(which "$command")
tdr="${tmq%/*}"
tex="${tmq##*/}"
if test -d "$tdr"; then cd "$tdr"; fi
#echo "cwd='$(pwd)' ################# d"

while $first || [ "${tmp:0:1}" == "l" ]
do
 first=false
 tmp=${tmp##*\ }
 tmq="$tmp"
 tmp=$(ls -l "$(which "$tmp")" 2>/dev/null)
 tdr="${tmq%/*}"
 tex="${tmq##*/}"
 if test -d "$tdr"; then cd "$tdr"; fi
# echo "cwd='$(pwd)' ################# d"
 if [ "$tmp" == "" ]
 then
  tmp=$(ls -l "$tex" 2>/dev/null)
  tmp=${tmp##*\ }
  if [ "$tmp" == "" ]
  then
   echo "$command is not in PATH"
#   package=$(bash -ic "$command -v 2>&1")
#   echo "package=$package XXXXX 0"
   bash -ic "alias '$command' > /dev/null 2>&1" > /dev/null 2>&1
   if [ $? -ne 0 ]
   then
    echo 'looking for package ...'
    package=$(bash -ic "$command -v 2>&1"| sed -e '0,/with:/d'| grep -v '^$')
   else
    echo 'alias, hence not looking for package'
   fi
#   echo "package=$package XXXXX 1"
   if [ "$package" != "" ]
   then
    echo "$str"
    echo "package: [to get command '$1']"
    echo -e "${inversvid}${package}${resetvid}"
   fi
   else
    echo "$tmp"
   fi
 else
  echo "$tmp"
 fi
done
tmp=${tmp##*\ }
if [ "$tmp" != "" ]
then
 echo "$str"
 program="$tex"
 program="$(pwd)/$tex"
 file "$program"
 if [ "$program" == "/usr/bin/snap" ]
 then
  echo "$str"
  echo "/usr/bin/snap run $command     # run $command "
  sprog=$(find /snap/"$command" -type f -iname "$command" \
   -exec file {} \; 2>/dev/null | sort | tail -n1)
  echo -e "${inversvid}file: $sprog$resetvid"
  echo "/usr/bin/snap list $command    # list $command"
  slist="$(/usr/bin/snap list "$command")"
  echo -e "${inversvid}$slist$resetvid"
 else
  package=$(dpkg -S "$program")
  if [ "$package" == "" ]
  then
   package=$(dpkg -S "$tex" | grep -e " /bin/$tex$" -e " /sbin/$tex$")
   if [ "$package" != "" ]
   then
    ls -l /bin /sbin
   fi
  fi
  if [ "$package" != "" ]
  then
   echo "$str"
   echo " package: /path/program  [for command '$1']"
   echo -e "${inversvid} $package ${resetvid}"
  fi
 fi
fi
echo "$str"
#alias=$(grep "alias $command=" "$HOME/.bashrc")
alias=$(bash -ic "alias '$command' 2>/dev/null"| grep "$command")
if [ "$alias" != "" ]
then
 echo "$alias"
fi
type=$(type "$command" 2>/dev/null)
if [ "$type" != "" ]
then
 echo "type: $type"
elif [ "$alias" == "" ]
then
 echo "type: $command: not found"
fi
cd "$curdir"

Sometimes there are two alternatives, e.g. for echo, both a separate compiled program and shell built-in command. The shell built-in will get priority and be used unless you use the full path of the separate program,

$ what-about echo
-rwxr-xr-x 1 root root 35000 jan 18  2018 /bin/echo
----------------------------------------------------------------------------------
/bin/echo: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically
linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0,
BuildID[sha1]=057373f1356c861e0ec5b52c72804c86c6842cd5, stripped
----------------------------------------------------------------------------------
 package: /path/program  [for command 'echo']
 coreutils: /bin/echo 
----------------------------------------------------------------------------------
type: echo is a shell builtin

Sometimes a command is linked to program, that might be hidden, e.g. the version of rename that I use,

$ what-about rename
lrwxrwxrwx 1 root root 24 maj 12  2018 /usr/bin/rename -> /etc/alternatives/rename
lrwxrwxrwx 1 root root 20 maj 12  2018 /etc/alternatives/rename -> /usr/bin/file-rename
-rwxr-xr-x 1 root root 3085 feb 20  2018 /usr/bin/file-rename
----------------------------------------------------------------------------------
/usr/bin/file-rename: Perl script text executable
----------------------------------------------------------------------------------
 package: /path/program  [for command 'rename']
 rename: /usr/bin/file-rename 
----------------------------------------------------------------------------------
type: rename is /usr/bin/rename

I have an alias for rm in order to avoid mistakes, and the alias has priority over the program in PATH. You can prefix with backslash, \rm to skip the alias and run the program directly. (Please remember that the alias applies only for the specific user, and not for sudo and other users, unless they have defined a similar alias.)

$ what-about rm
-rwxr-xr-x 1 root root 63704 jan 18  2018 /bin/rm
---------------------------------------------------------------------------
/bin/rm: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV),
dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for
GNU/Linux 3.2.0, uildID[sha1]=864c9bbef111ce358b3452cf7ea457d292ba93f0,
stripped
---------------------------------------------------------------------------
 package: /path/program  [for command 'rm']
 coreutils: /bin/rm 
---------------------------------------------------------------------------
alias rm='rm -i'
type: rm is /bin/rm
4
  • Thank you, that bash script is terrific. I'm learning quite a lot reading it.
    – dotancohen
    Commented Jun 9, 2022 at 15:40
  • @dotancohen, You are welcome, I'm glad I could help you.
    – sudodus
    Commented Jun 9, 2022 at 15:41
  • Your answer does not attempt to answer the question, which is about terminology.
    – Kusalananda
    Commented Jun 9, 2022 at 18:08
  • 2
    @Kusalananda, About terminology, yes, but also 'how I could determine what an arbitrary thing on the cli is', which I interpret as a [software] method to find out. Anyway, the other answers focus on terminology, so both aspects are given attention.
    – sudodus
    Commented Jun 9, 2022 at 20:41

You must log in to answer this question.

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