What is /bin/true?
/bin/true
is a command that returns 0 (a truth value in the shell).
Its purpose is to use in places in a shell script where you would normally use a literal such as "true" in a programming language, but where the shell will only take a command to run.
/bin/false
is the opposite that returns non-zero (a false value in the shell).
Why is /bin/true 27168 bytes in size?
Because apart from returning 0 it also handles help and version options, plus it contains some comments inside.
You can figure it by yourself by cloning the sources from Github, and looking at the content of coreutils/src/true.c.
How can I understand the role of /bin/true command in docker run ... command?
Running and thus creating a new container even if it terminates still keeps the resulting container image and metadata lying around which can still be linked to.
So when you run docker run ... /bin/true
you are essentially creating a new container for storage purposes and running the simplest thing you can.
In Docker 1.5 was introduced the docker create
command so I believe you can now "create" containers without confusingly running something like /bin/true
See: docker create
This is new method of managing data volume containers is also clearly documented in the section Creating and mounting a Data Volume Container
Purpose of #!/bin/false in bash script
In general, let’s consider a file testcode
with bash code in it
#!/bin/bash
if [ "$0" = "${BASH_SOURCE[0]}" ]; then
echo "You are executing ${BASH_SOURCE[0]}"
else
echo "You are sourcing ${BASH_SOURCE[0]}"
fi
you can do three different things with it:
$ ./testcode
You are executing ./testcode
This works if testcode has the right permissions and the right shebang. With a shebang of #!/bin/false
, this outputs nothing and returns a code of 1 (false).
$ bash ./testcode
You are executing ./testcode
This completely disregards the shebang (which can even be missing) and it only requires read permission, not executable permission. This is the way to call bash scripts from a CMD command line in Windows (if you have bash.exe
in your PATH...), since there the shebang machanism doesn’t work.
$ . ./testcode
You are sourcing ./testcode
This also completely disregards the shebang, as above, but it is a complete different matter, because sourcing a script means having the current shell execute it, while executing a script means invoking a new shell to execute it. For instance, if you put an exit
command in a sourced script, you exit from the current shell, which is rarely what you want. Therefore, sourcing is often used to load function definitions or constants, in a way somewhat resembling the import
statement of other programming languages, and various programmers develop different habits to differentiate between scripts meant to be executed and include files to be sourced. I usually don’t use any extension for the former (others use .sh
), but I use an extension of .shinc
for the latter. Your former colleague used a shebang of #!/bin/false
and one can only ask them why they preferred this to a zillion other possibilities. One reason that comes to my mind is that you can use file
to tell these files apart:
$ file testcode testcode2
testcode: Bourne-Again shell script, ASCII text executable
testcode2: a /bin/false script, ASCII text executable
Of course, if these include files contain only function definitions, it’s harmless to execute them, so I don’t think your colleague did it to prevent execution.
Another habit of mine, inspired by the Python world, is to place some regression tests at the end of my .shinc
files (at least while developing)
... function definitions here ...
[ "$0" != "${BASH_SOURCE[0]}" ] && return
... regression tests here ...
Since return
generates an error in executed scripts but is OK in sourced scripts, a more cryptic way to get the same result is
... function definitions here ...
return 2>/dev/null || :
... regression tests here ...
Why entrypoint is set to 'bin/true' in docker-compose.yml
This is an older version of Docker-compose. The reason for doing this is to start a container, which creates volumes and then exits.
So the below starts a container and exists
db-data:
image: mongo:3.2
volumes:
- /data/db
- /var/lib/mongodb
- /var/log/mongodb
entrypoint: /bin/true
Inside that container these volumes path get created.
- /data/db
- /var/lib/mongodb
- /var/log/mongodb
Then mongo uses volumes_from
to store data in this container
db:
image: mongo:3.2
restart: always
ports:
- "27017:27017"
volumes_from:
- db-data
volumes_from
is no deprecated in Compose 3.X and should not be used. Instead either you should use named of anonymous volumes.
So the compose would change to something like below
Anonymous volumes
version: '3.3'
....
db:
image: mongo:3.2
restart: always
ports:
- "27017:27017"
volumes:
- /data/db
- /var/lib/mongodb
- /var/log/mongodb
Named volumes
version: '3.3'
....
db:
image: mongo:3.2
restart: always
ports:
- "27017:27017"
volumes:
- mongodata:/data/db
- mongodata:/var/lib/mongodb
- mongodata:/var/log/mongodb
volumes:
mongodata: {}
How do I install the true binary on MacOS?
It's in /usr/bin
so change all references from /bin/true
to true
as it's reasonable to expect /usr/bin
to be in the $PATH
.
That or a load of tedious cross-platform conditional stuff...
Why my bash if statement keeps on returning true?
The output of the modprobe command contains a trailing space.
Try:
if ! [[ "$(modprobe -n -v cramfs 2> /dev/null | tail -1)" =~ 'install /bin/true' ]];
or:
if ! modprobe -n -v cramfs 2> /dev/null | tail -1 | grep -q 'install /bin/true'
or (I think this is all you are trying to accomplish):
if ! modprobe -q cramfs; then ...
functions /bin/false in shell script makes negative effect
The thing is that:
action "Test" /bin/false
returns 1
that causes command after ||
to execute as the failure action. Effectively this behaves like this:
[ 0 -eq 0 ] && { action "Test" /bin/false || action "Test" /bin/true; }
This is more of a reason to use if/else/fi
and get the right behavior:
echo "###############"
if [ 0 -eq 0 ]; then
action "Test" /bin/false
else
action "Test" /bin/true
fi
This will output:
Test [FAILED]
Related Topics
How to Mount from Command Line Like the Nautilus Does
How to Prepend a Directory the Library Path When Loading a Core File in Gdb on Linux
Remove Only Files in Directory on Linux Not Directories
Determine Target Isa Extensions of Binary File in Linux (Library or Executable)
Writing to Eventfd from Kernel Module
Cmake Complains "The Cxx Compiler Identification Is Unknown"
Why I Cannot Override Search Path of Dynamic Libraries with Ld_Library_Path
Exclude All Permission Denied Messages from "Du"
What Is Start-Stop-Daemon in Linux Scripting
What Are Ld-Linux.So.2 and Linux-Gate.So.1
Differencebetween .Got and .Got.Plt Section
Tcp Handshake with Sock_Raw Socket
Which Context Are Softirq and Tasklet In
Linux Custom Executable Globally Available
How to Use Aliased Commands with Xargs
List of Possible Internal Socket Statuses from /Proc