How can I create a file and make it executable without typing the filename twice?

199 Views Asked by At

I would like to be able to chmod +x and touch a file in one go without having to list the file name twice as in touch foo && chmod +x foo. Is there a way to do this is in one whack? Here is some pseudo-code explanation describing the expected behavior:

chmod <placeholder> && touch <placeholder> <-redirect- "filename"

I get sick of typing in one off commands and then to go back and execute the same command a few times for different files I have to edit the filename twice in each command. In my psuedo-code example I would only have to return to the previously entered command and edit only the filename string at the end.

I have tried,

touch "$(echo foo && chmod +x !$)"

but the filename is neither at the end of the string, and it doesn't seem to work because the last argument !$ is the one passed to the command before touch.

4

There are 4 best solutions below

2
Gilles Quénot On BEST ANSWER

Like this:

$ touch foo && chmod +x $_

Now:

$ ls -l foo
-rwxrwxr-x 1 me me    0 mars  30 19:16 foo
0
markp-fuso On

If all you ever do is issue the touch / chmod pair, a simple function should suffice:

touchx() { touch "$1"; chmod +x "$1"; }

Taking for a test drive:

$ touchx myscript.sh
$ ls -l myscript.sh
-rwxrwx--x+ 1 username None 0 Mar 29 14:37 myscript.sh

On the other hand if the objective is to support a series of unknown-beforehand set of commands, another function may come in handy:

multicmd() {
    fname="$1"
    shift
    for cmd in "$@"
    do
        echo "##### $cmd $fname"
        $cmd "$fname"
    done
}

# or as a one-liner:

multicmd() { fname="$1"; shift; for cmd in "$@"; do echo "##### $cmd $fname"; $cmd "$fname"; done; }

Taking for a test drive

$ multicmd myscript.sh rm touch 'chmod +x' 'file' 'ls -l'
##### rm myscript.sh
##### touch myscript.sh
##### chmod +x myscript.sh
##### file myscript.sh
myscript.sh: empty
##### ls -l myscript.sh
-rwxrwx--x+ 1 username None 0 Mar 29 14:54 myscript.sh
0
tjm3772 On

Depending on your needs, umask may be a simple solution. umask +x will cause any file you create using the current shell to have execution privileges by default for example. If you're going to make a lot of files during a session and don't want to individually chmod them or write custom functions this would be a viable alternative.

The downside is that if you touch an existing file, this won't change its permissions. If that's what you want then use one of the other solutions instead.

2
Léa Gris On

The install command is especially designed for this kind of purposes and can do much more:

$ install -T -m755 /dev/null foo
$ ls -l foo
-rwxr-xr-x 1 léa léa 0 mars  30 19:35 foo