11

I have a directory on an nfs mount, which on the server is at /home/myname/.rubies

Root cannot access this directory:

[mitchell.usher@server ~]$ stat /home/mitchell.usher/.rubies
  File: `/home/mitchell.usher/.rubies'
  Size: 4096            Blocks: 8          IO Block: 32768  directory
Device: 15h/21d Inode: 245910      Links: 3
Access: (0755/drwxr-xr-x)  Uid: (  970/mitchell.usher)   Gid: (  100/   users)
Access: 2016-08-22 15:06:15.000000000 +0000
Modify: 2016-08-22 14:55:00.000000000 +0000
Change: 2016-08-22 14:55:00.000000000 +0000

[mitchell.usher@server ~]$ sudo !!
sudo stat /home/mitchell.usher/.rubies
stat: cannot stat `/home/mitchell.usher/.rubies': Permission denied

I am attempting to copy something from within that directory to /opt which only root has access to:

[mitchell.usher@server ~]$ cp .rubies/ruby-2.1.3/ -r /opt
cp: cannot create directory `/opt/ruby-2.1.3': Permission denied

[mitchell.usher@server ~]$ sudo !!
sudo cp .rubies/ruby-2.1.3/ -r /opt
cp: cannot stat `.rubies/ruby-2.1.3/': Permission denied

Obviously I can do the following (and is what I've done for the time being):

[mitchell.usher@server ~]$ cp -r .rubies/ruby-2.1.3/ /tmp/
[mitchell.usher@server ~]$ sudo cp -r /tmp/ruby-2.1.3/ /opt/

Is there any way to do this that wouldn't involve copying it as an intermediary step or changing permissions?

Ketan Maheshwari
  • 9,054
  • 6
  • 40
  • 53
Mitch
  • 1,188
  • 3
  • 13
  • 24
  • `cp -Rp /home/mitchell.usher/.rubies /tmp/templocation; sudo mv /tmp/templocation/ruby-2.1.3 /opt` will this not work ? If no, why ? – MelBurslan Aug 22 '16 at 15:31
  • @MelBurslan that's what I did, as stated in the question. But let's say it's a 50 GB file that won't fit anywhere else on the filesystem, then I wouldn't be able to `cp /tmp/tmpfile` – Mitch Aug 22 '16 at 17:45

3 Answers3

29

You can use tar as a buffer process

cd .rubies
tar cf - ruby-2.1.3 | ( cd /opt && sudo tar xvfp - )

The first tar runs as you and so can read your home directory; the second tar runs under sudo and so can write to /opt.

Stephen Harris
  • 42,369
  • 5
  • 94
  • 123
  • 1
    How is this on memory? If I have a 10 GB file, is that going to fill 10 GB of memory before it pipes and un-tars, or will it un-tar as it tars? – Mitch Aug 22 '16 at 18:39
  • 6
    They run in parallel; a typical pipe has a 64Kbyte buffer. Nothing to worry about :-) http://unix.stackexchange.com/questions/11946/how-big-is-the-pipe-buffer for pipe size details. – Stephen Harris Aug 22 '16 at 18:50
  • See also [In what order do piped commands run?](http://unix.stackexchange.com/q/37508/23408) (in particular, [my answer](http://unix.stackexchange.com/q/37508/23408#144033)). – Scott - Слава Україні Aug 22 '16 at 21:12
  • `cpio` can be used in much the same way. – Toby Speight Aug 23 '16 at 07:34
  • If you have GNU tar, you can save the subshell by using its `-C` argument to change directory (i.e. `tar cf - ruby-2.1.3 | sudo tar -C /opt xpf -`). Might be worth mentioning that you want to ensure that `sudo` won't ask your password (e.g. through a `sudoers` entry or cached credentials). – Toby Speight Aug 23 '16 at 07:37
  • @TobySpeight Why do you need to prevent it from asking for a password? Unless you're running this unattended, but that's true for any unattended use of `sudo`. – Barmar Aug 24 '16 at 17:36
  • @Barmar - because its stdin is coming from a pipe, not from your terminal. So how are you going to give it the password? – Toby Speight Aug 24 '16 at 17:40
  • `sudo` will read the password from `/dev/tty` and not from stdin. – Stephen Harris Aug 24 '16 at 18:47
6

You could use rsync or scp to copy from user@localhost to the local directory.

Example for rsync:

# rsync "$real_user@localhost:$PWD/.rubies/ruby-2.1.3" /opt

You could alternatively

$ rsync .rubies/ruby-2.1.3 "root@localhost:/opt"

if you let root access localhost directly (not recommended; we normally prefer root access to be via sudo).

Toby Speight
  • 8,460
  • 3
  • 26
  • 50
-4

You can make a second entry in the FAT (or whatever).
I do this for my HOSTS file. I have a link in a writable directory that refers to the file and it has different permissions, so I have /Hosts/HOSTS that I can modify easily, and the changes are put in both (i.e. "the one") file(s). It's 2 entries for 1 file. I don't remember the command, sorry.

For you, you make a link to /opt for all the files in .rubies, and when you change anything in /opt, it is the same file as in .rubies.

Michael Mrozek
  • 91,316
  • 38
  • 238
  • 232
Engineer
  • 119
  • 5
  • 4
    This is false and misleading, besides not answering the question. – Wildcard Aug 23 '16 at 01:37
  • It is only false because we're dealing with a different file system. The answerer was obviously referring to hard links which do operate as mentioned, although not applicable for this question. – Julie Pelletier Aug 23 '16 at 04:13
  • Thanks Wildcard, I had a line in my answer about getting a bunch of flack but it was edited out when Michael improved it. :p – Engineer Aug 25 '16 at 01:24