Rclone update and elevation

I have my system configured to do rclone selfupdate via a shell script that updates other things. This worked until rclone actually found an update, at which point, this:
Error: /usr/bin/rclone: file is not writable, run self-update as root

It would be better were rclone to request elevation, interactively. For if I replace rclone selfupdate with sudo rclone selfupdate, then even the check for updates requires root; thus, I have to grant root access - via entering my password, unless I give the whole script root - even if there is no update to perform. What if I do give the whole script root? Then, again: even if there is no update (of rclone or anything else) to perform, I must enter the password - unless I use sudoers and unless something else in the script has caused elevation. I could use sudoers. I would rather though that rclone prompted for elevation when and indeed only when it needs to install an updated version.

Also: sudo rclone selfupdate performs the update but also spits out the following. NOTICE: Config file "/root/.config/rclone/rclone.conf" not found - using defaults. That message seems to suggest that I am trying to make rclone perform its normal operations as root.

It isn't a script as it's a binary file.

felix@gemini:~$ file /usr/bin/rclone
/usr/bin/rclone: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=mRVLVy7TYHDaBXvQGelh/yEKI46AXJVmeEBCvhu_I/Sc6m3VLNYYBEHOBo_snx/SDrtLzBCUSE9-N_pEZR9, stripped

and it's owned by root

-rwxr-xr-x 1 root root 43831296 Jul 20 15:47 /usr/bin/rclone****

You can lock down sudoers to /usr/bin/rclone selfupdate if you want to only allow that binary to run without a password with that specific command.

That's just saying you don't have a config file as that's a normal message. You can always make a blank config file if the message is annoying.

Thanks for the reply.

The script at issue is, as I said, by me.

Sudoers: I know how it works. The point is as follows. Programs should be given elevated permissions only when they need them. The rclone update check does not need elevation - only the actual update does.

The message about the lack of a config file does have the connotation that one intends to run rclone as root, and that connotation is unfortunate because (1) most people will not do that, (2) doing it would be a bad idea.

integration with a miryad interactive systems will grow rclone beyond reasons.
i will not do it.
please use sudo.

the confusing message about config was fixed in 1.56 (released 2 days ago).

there are many ways to solve elevation issue without adding new features to rclone. use any of them to your taste:

  • /path/to/your/user/writable/rclone selfupdate
  • rclone selfupdate --output /path/to/writable/rclone (see rclone selfupdate) and then copy updated executable using your elevation script
  • use sudo rclone selfupdate and configure sudo to ask for elevation using your system specific instuctions
  • use graphical replacement for sudo provided by your kde/gnome/xfce/whatever
  • run rclone selfupdate --check, analyze its output in your script then run selfupdate only when needed

or:

  • wait 5-8 months until we deploy planned apt/yum repository on rclone.org so by early 2022 you will be able to use apt/yum to maintain latest rclone

I was unaware of rclone selfupdate --check. That command looks good, except that seemingly, in order to use it in a script, I have to write a way of parsing its output.

An apt repository? That will be marvellous.

I wrote some Bash to interpret the output of the check command. It was fiddly. It is as follows.

function upd_rclone
{
	if output=$(rclone selfupdate --check); then
		local lineCount
		lineCount=$(wc -l <<< "${output}")

		if [[ $lineCount -gt 1 ]] ; then

			local line_1 line_1_withoutSpaces version_current
			line_1=$(sed "1q;d" <<< "${output}")
			# echo "line_1 is <$line_1>"
			line_1_withoutSpaces="${line_1//[[:blank:]]/}"
			# echo "line_1_withoutSpaces is <$line_1_withoutSpaces>"
			version_current=$(cut -d':' -f2 <<< "${line_1_withoutSpaces}")
			echo "version_current is <$version_current>"

			local line_2 line_2_withoutSpaces line_2_withoutParenthesis version_new
			line_2=$(sed "2q;d" <<< "${output}")
			# echo "line_2 is <$line_2>"
			line_2_withoutSpaces="${line_2//[[:blank:]]/}"
			# echo "line_2_withoutSpaces is <$line_2_withoutSpaces>"
			line_2_withoutParenthesis=${line_2_withoutSpaces%(*}
			# echo "line_2_withoutParenthesis is <$line_2_withoutParenthesis>"
			version_new=$(cut -d':' -f2 <<< "${line_2_withoutParenthesis}")
			echo "version_new is <$version_new>"
			
			if (( $(echo "$version_new $version_current" | awk '{print ($1 > $2)}') )); then
				echo 'New version available.'
				sudo rclone selfupdate
			else
				echo 'No new version of rclone available.'
			fi
			return 0
		fi
		return 1
	fi
}
rc=$(which rclone)
tmp=$(mktemp /tmp/rclone.XXXX)
cp "$rc" "$tmp"
"$rc" selfupdate --output "$tmp"
cmp "$tmp" "$rc" || sudo cp "$tmp" "$rc"
rm "$tmp"

updates:

  1. mktemp
  2. quotes

Use tmp=$(mktemp) to avoid security issues

1 Like

Thank you both. (I note that the linter called 'shellcheck' recommends some extra quoting of variables. But ivandeex's method is much simpler than the one I proposed!)

1 Like