Tag Archives: shell

How to run rsync on remote host with sudo

Sometimes I want to transfer files including ownership. This is not possible as normal user as the chown(2) system call requires special privileges, that is: uid == 0. However, I do not want to open ssh access for root, but go with the usual way to elevate my privileges: sudo.

I will go through common solutions presented on the web and explain why these do not work at all without significant modifications on the remote host and then present a working solution using X11-Forwarding that is less invasive.

Continue reading

tmux update-environment

tmux is one of the tools I use everyday. But one thing always annoyed me: even though I am using X11 forwarding and ssh-agent forwarding when re-attaching to a session, the DISPLAY and SSH_AUTH_SOCK environment variables are often wrong. Environment variables are initialized only once when the window was created. tmux is able to update some environment variables for new windows and panes based on the update-environment setting, however, existing shell windows cannot be updated.

Continue reading

bash: reuse last argument from previous command

Reuse the last argument of the previous command with !$:

$ echo abc def
abc def
$ echo !$
def

A common use case would be mkdir and cd:

$ mkdir foo
$ cd !$

You can also insert the last argument of the previous command and continue typing with <ESC>.:

$ echo abc def
abc def
$ echo <ESC>. ghi
def ghi

Oh, the little things… 🙂

bash: for-loop with glob patterns

It is common to use a for-loop with glob patterns:

for i in *.txt; do
    mv $i $i.old
done

But if the glob pattern does not match anything it will be preserved unchanged in the command. This results in command execution of mv *.txt *.txt.old which fails because no file named *.txt (literally!) exists.

As this is not the desired behavior, here is a way how to do this as expected without forking using the nullglob bash shell option.

oldnullglob=$(shopt -p nullglob)
shopt -s nullglob

for i in *.txt; do
    mv $i $i.old
done

eval "$oldnullglob" 2>/dev/null
unset oldnullglob

This will silently prevent the execution of the mv command. If you use failglob instead of nullglob bash will interrupt the evaluation of any command if the glob pattern did not match anything.

Disclaimer: Be careful with this option, as this will not be the expected behavior in all cases. Most (in)famously it breaks bash-completion if you set it in your interactive bash session. I suggest to use it temporary only.