What Is /Bin/True

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



Leave a reply



Submit