TIL about the install
command on *nix systems. A quick GitHub search for the term brought
up a ton of matches1. I’m surprised I just found out about it now.
Often, in shell scripts I need to:
- Create a directory hierarchy
- Copy a config or binary file to the new directory
- Set permissions on the file
It usually looks like this:
# Create the directory hierarchy. The -p flag creates the parent directories
# if they don't exist
mkdir -p ~/.config/app
# Copy the current config to the newly created directory. Here, conf already
# exists in the current folder
cp conf ~/.config/app/conf
# Set the file permission
chmod 755 ~/.config/app/conf
Turns out, the install
command in GNU coreutils2 can do all that in one line:
install -D -m 755 conf ~/.config/app/conf
You can check the file status with:
stat ~/.config/app/conf
On my machine, this prints:
File: /Users/rednafi/.config/app
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 1,16 Inode: 16439606 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 501/ rednafi) Gid: ( 20/ staff)
Access: 2024-07-28 20:51:42.793765043 +0200
Modify: 2024-07-28 20:51:42.793765043 +0200
Change: 2024-07-28 20:51:42.793907876 +0200
Birth: 2024-07-28 20:51:42.793765043 +0200
The -D
flag directs install
to create the destination directories if they don’t exist,
and the -m
flag sets file permissions. The result is the same as the three lines of
commands before.
It’s common for Makefiles in C/C++ projects to install binaries like this:
install -D -m 744 app_bin /usr/local/bin/app_bin
It copies app_bin
to /usr/local/bin
, creates the parent directory hierarchy if
necessary, and sets permissions on the binary so only the current user has read, write, and
execute permissions, while others have read-only access.
You can also set directory permissions:
install -d -m 600 foo/bar/bazz
This creates the directory hierarchy first and then sets the permission. Here’s how they look:
tree foo
Output:
foo
└── bar
└── bazz
3 directories, 0 files
Then you can copy a file to the destination and set file permissions with another install
command if needed.
You can also set user or group ownership while copying a file:
install -D -m 644 -o root -g root seed.db /var/lib/app/seed.db
This command copies seed.db
to the destination, creates the directory if needed, and gives
access to the root user and group with the -o
and -g
flags, respectively.
There are a few other options you can read about in the man pages, but I haven’t needed anything beyond the above.
Recent posts
- Explicit method overriding with @typing.override
- Quicker startup with module-level __getattr__
- Docker mount revisited
- Topological sort
- Writing a circuit breaker in Go
- Discovering direnv
- Notes on building event-driven systems
- Bash namerefs for dynamic variable referencing
- Behind the blog
- Shell redirection syntax soup