# Moving files on Linux

The humble ``mv`` command is one of those useful tools you find on every POSIX box you encounter.
Its job is clearly defined, and it does it well: move a file from one place in a file system to another.
But Linux is nothing if not flexible, and there are other options for moving files, and sometimes using different tools provide small advantages that fit  perfectly with a specific use case.

Before straying too far from ``mv``, take a look at the default results of the command.
First, create a directory and generate some files with permission set to 777:

```
$ mkdir example
$ touch example/{foo,bar,baz}
$ for i in example/*; do ls /bin > "${i}"; done
$ chmod 777 example/*
```

Take a look at the inode of one of the sample files:

```
$ ls --inode example/foo
7476868 example/foo
```

As a test, move that file from the example directory to your current directory, and then view the file attributes:

```
$ mv example/foo .
$ ls -l -G -g --inode
7476868 -rwxrwxrwx. 1 29545 Aug  2 07:28 foo
```

The original file, along with its existing permissions, have been moved.
Its inode has not changed.

That's the way the ``mv`` tool is programmed to move a file: leave the inode unchanged (unless the file is being moved to a different file system), and preserve its ownership and permissions.

Other tools provide slightly different options.

## Copy and remove

On some systems, the move action is a true move action: bits are removed from one point in the file system and reassigned to another.
This has largely fallen out of favor, and move actions are now either reassignments of attributes (an inode simply points to a different location in your file organization) or an amalgamations of a copy action followed by a remove action.
The intent of this design philosophy is to ensure that, should a move fail, a file is not left in pieces.

You can mimic a move using the literal ``cp`` and ``rm`` (or [trash](https://gitlab.com/trashy) if you have it) commands:

```
$ cp example/foo .
$ ls -l -G -g --inode
7476869 -rwxrwxr-x. 29545 Aug  2 11:58 foo
$ trash example/foo
```

The ``cp`` command, unlike ``mv``, creates a brand new data object in your file system.
It has a new inode location, and it is subject to your active umask.
The new ``foo`` file in this example got 775 permission because the umask of the location specifically excludes write permissions:

```
$ umask
0002
```

For more information about umask, read Alex Juarez's article about [file permissions](https://opensource.com/article/19/8/linux-permissions-101#umask).


## Cat and remove

Similar to a copy and remove, using the ``cat`` (or ``tac``, for that matter) command gets different permissions when your "moved" file is created.
Assuming a fresh test environment with no ``foo`` in the current directory:

```
$ cat example/foo > foo
$ ls -l -G -g --inode
7476869 -rw-rw-r--. 29545 Aug 8 12:21 foo
$ trash example/foo
```

This time, a new file has been created with no prior permissions set.
The result is entirely subject to the umask setting, which blocks no permission bit for the user and group (the executable bit is not granted for new files regardless of umask), but it blocks the write (value 2) bit from others.
The result is the file with 664 permission.


## Rsync

The ``rsync`` command is a robust multipurpose tool to send files between hosts and file system locations.
It has many options available to it, including the ability to make its destination mirror its source.

You can copy and then remove a file using the ``--remove-source-files`` option, along with whatever ``rsync`` option you choose to perform the synchronization (a common, general-purpose one is ``--archive``).
A word of warning: do not confuse this option for the ``--delete`` options, which remove files from your *destination* directory.
Mis-using the ``--delete`` options can wipe out most of you data, and it's recommended that you avoid those options except in a test environment.

```
$ rsync --archive --remove-source-files example/foo .
$ ls example
bar  baz
$ ls -lGgi
7476870 -rwxrwxrwx. 1 seth users 29545 Aug 8 12:23 foo
```

File permission and ownership is retained, the timestamp is updated, and the source file is removed.

You can override some of these defaults, changing permission and modification settings:

```
$ rsync --chmod=666 --times \
--remove-source-files example/foo .
$ ls example
bar  baz
$ ls -lGgi
7476871 -rw-rw-r--. 1 seth users 29545 Aug 8 12:55 foo
```

The umask of the destination is respected, so the ``--chmod=666`` option results in a file with 664 permissions.


## Setting permissions with the install command

The ``install`` command is a copy command specifically geared toward developers, and mostly invoked as part of the install routine of software compiling.
It's not well known among users (and I do often wonder why it got such an intuitive name, leaving mere acronyms and pet names for package managers), but it's actually a very useful way to put files where you want them.
There are many options for the ``install`` command, including a ``--backup`` (as with [GNU mv](LINK TO MY MV ARTICLE)), a ``--compare`` command to avoid "updating" a newer copy of a file, and much more.

Unlike ``cp`` and ``cat``, but exactly like ``mv``, the ``install`` command can copy a file while preserving the file's time stamp:

```
$ install --preserve-timestamp example/foo .
$ ls -l -G -g --inode
7476869 -rwxr-xr-x. 1 29545 Aug  2 07:28 foo
$ trash example/foo
```

The file has been copied to a new inode, but its mtime has not been changed.
The permissions, however, have been set to the ``install`` default of 755.

You can set permissions, owner, and group:

```
$ install --preserve-timestamp \
--owner=skenlon \
--group=dialout \
--mode=666 example/foo .
$ ls -li
7476869 -rw-rw-rw-. 1 skenlon dialout 29545 Aug  2 07:28 foo
$ trash example/foo
```

## Moving, copying, and removing

Files contain data, and the really important files contain *your* data.
Learning to manage them wisely is important, and now you know the tools you have to work with to ensure that your data is handled in exactly the way you want it to be.
Do you have a different way of managing your data?
Tell us your ideas in the comments.