How to export directory created inside the Docker image to the host machine? - linux

The program I'm running inside the Docker image, first creates a directory and writes some file into the directory.
To transfer the directory onto the host machine, I've mounted a datadir/ and then moved the directory created inside the image into the mounted directory, e.g.:
mkdir datadir
DATADIR=datadir/
docker run -i \
-v $(pwd)/$DATADIR:/$DATADIR/ ubuntu \
bash -c "mkdir /x1 && echo 'abc' > x1/test.txt && mv x1 $DATADIR"
But when I tried to access datadir/x1, it has root as the owner and it comes with read-only permissions:
$ mv datadir/x1/ .
mv: cannot move 'datadir/x1/' to './x1': Permission denied
$ ls -lah datadir/x1/
total 12K
drwxr-xr-x 2 root root 4.0K Jun 28 16:38 .
drwxrwxr-x 3 alvas alvas 4.0K Jun 28 16:38 ..
-rw-r--r-- 1 root root 4 Jun 28 16:38 test.txt
Is mounting the additional volume and copying the created directory inside the image the right approach to move files between the Docker image and the host machine? If not, what's the "canonical" way to perform the same operation?
About the directory permissions, what should be the correct way to assign the host machine permission to any files inside the mounted volume?
I've tried to chmod -R 777 inside the Docker image but I don't think that's the safe approach, i.e.:
$ docker run -i -v $(pwd)/$DATADIR:/$DATADIR/ -i ubuntu bash -c "mkdir /x1 && echo 'abc' > x1/test.txt && mv x1 $DATADIR && chmod -R 777 $DATADIR"
$ mv datadir/x1/ .
$ ls -lah x1
total 12K
drwxrwxrwx 2 root root 4.0K Jun 28 16:47 .
drwxrwxr-x 12 alvas alvas 4.0K Jun 28 16:47 ..
-rwxrwxrwx 1 root root 4 Jun 28 16:47 test.txt

To avoid permission issues use docker cp
For example:
# This is the directory you want to save the outputs
mkdir datadir
# We create a directory and file inside it, inside the Docker image.
# And we are naming the Docker image "thisinstance"
docker run -i --name thisinstance ubuntu \
bash -c "mkdir /x1 && echo 'abc' > x1/test.txt"
# Copies the new directory inside the Docker image to the host.
docker cp thisinstance:/x1 datadir/
# Destroy the temporary container
docker rm thisinstance
# Check the ownership of the directory and file
ls -lah datadir/x1/
[out]:
drwxr-xr-x 3 alvas 679754705 102B Jun 29 10:36 ./
drwxr-xr-x 3 alvas 679754705 102B Jun 29 10:36 ../
-rw-r--r-- 1 alvas 679754705 4B Jun 29 10:36 test.t

Related

Strange problem with find command on ubuntu

I used the 'find' command to find a file and encountered a strange issue:
the file exists, but 'find' can't find it
I found two .sock in /run with 'sudo find /run -name docker.sock'
$sudo find /run -name docker.sock
/run/march/docker.sock
/run/docker.sock
I got nothing when run 'sudo find /var -name docker.sock' and 'sudo find /var/run -name docker.sock'
$sudo find /var -name docker.sock
$sudo find /var/run -name docker.sock
$
but in fact there are two .sock in /var/run/, any comments?
$ls -al /var/run/docker.sock
srwxrwxrwx+ 1 root docker 0 Oct 18 20:45 /var/run/docker.sock
$ls -al /var/run/march/docker.sock/
total 0
drwxr-xr-x 2 root root 40 Oct 31 20:35 .
drwxr-xr-x 5 root root 100 Oct 31 20:35 ..
$ls -al /var/run/march/
total 0
drwxr-xr-x 5 root root 100 Oct 31 20:35 .
drwxr-xr-x 34 root root 1120 Oct 31 23:45 ..
drwxr-xr-x 2 root root 40 Oct 31 20:35 docker
drwxr-xr-x 2 root root 40 Oct 31 20:35 docker.pid
drwxr-xr-x 2 root root 40 Oct 31 20:35 docker.sock
$
$
BTW it's on Ubuntu 20.04.2 LTS
Thanks in advance
As /var/run is a symbolic link to /run, you have to tell find to follow links :
sudo find -L /var/run -name docker.sock

`ls -l` for all parent directories

I want to get a list of all directory permissions from current folder to /. For example, for the directory: /var/lib/program/subfolder, I want an output such as:
$ pwd
/var/lib/program/subfolder
$ magic_ls_-l_command somefile
drwxr-xr-x 10 root root 4096 May 15 20:20 var
drwxr-xr-x 10 root root 4096 May 15 20:20 lib
drwxrwxr-x 10 root user 4096 May 16 20:21 program
drwxrwxr-x 10 root user 4096 May 16 20:21 subfolder
-rwxrwxr-- 1 root user 4096 May 16 20:22 somefile
I don't care about the order (from /var to /subfolder or the other way around), the number of hard links or even the date. I just wrote them down to emulate the ls -l output. Also, I don't care how each filename in printed (/var and /lib, var and lib, or /var and /var/lib). I'm just interested in the ownership of each file/directory in the path from the choosen file or pwd to /.
In case I should install some program, I'm under Ubuntu 20.04.
This question has already been answered in superuser.com (I don't know if I can mark a question from one site as duplicate from another). The solution is as simple as writing (assuming I am in the same directory as the target filename):
$ namei -l $(pwd)/somefile ## or `namei -l $(realpath -s somefile)`
Because of -l, it lists basic permissions in long format for each parent directory.
I have to use pwd/realpath because namei doesn't resolve relative paths. If I'm not in the target directory, just write the full path.
I made this small script that does this. I use cd "$1"; pwd to get the current directory so that paths are not canonicalized (say, if you try magic-ls . and your current directory is /var/lib/postgres, but that is a symlink to /mnt/postgres, you will get /var, /var/lib and /var/lib/postgres, while using realpath you would get /mnt and /mnt/postgres)
magic-ls() {
local current=$(cd "$1"; pwd)
while [[ $current != '/' ]]; do
ls -ld "$current"
current=$(dirname "$current")
done
}
Here's an example output:
[leodag#desk ~]$ magic-ls
drwx------ 1 leodag leodag 2722 jun 21 13:49 /home/leodag
drwxr-xr-x 1 root root 18 mai 2 2019 /home
By the way it will also work with no argument since cd "" does not change your directory.
Edit: removed realpath from the while check, since that could lead to unexpected results if there was a link to / in the path, and was unneeded.
I wrote a bash script for you. It'll have some bugs, if you have space in names. If it bothers you, I'm happy for changes recommendations in the comments.
#!/bin/bash
if [ ! -z "$1" ] && [ -e "$1" ]
then
path=`realpath -s "$1"` # read argument as absolute path
else
path="$PWD" # No valid argument, so we take pwd
fi
paths=""
while [ "$path" != / ];do
paths+=" $path"
path=`dirname "$path"`
done
paths+=" $path" # Adding / to pathlist too
ls -ld $paths
With realpath -s you can catch the absolute path, but you wont follow the link. If no argument is given, we will use pwd as the file/directory to list.
We append each path to a list. This gives us the advantage of a better layout in the end, so that we get a nice table because we run ls only once.
Output:
bobafit:~$ magic_ls_-l_command /usr/bin/python3
drwxr-xr-x 21 root root 4096 Jun 20 10:07 /
drwxr-xr-x 14 root root 4096 Sep 5 2019 /usr
drwxr-xr-x 2 root root 110592 Jun 20 10:07 /usr/bin
lrwxrwxrwx 1 root root 9 Apr 7 12:43 /usr/bin/python3 -> python3.8
Just using parameter expansion:
#!/usr/bin/env bash
path="$1"
while test -n "$path"; do
ls -lLd "$path"
path="${path%/*}"
done
calling method :
bash test.sh /var/lib/program/subfolder/somefile
giving
-rw-r--r-- 1 root root 0 Jun 21 18:49 /var/lib/program/subfolder/somefile
drwxr-xr-x 1 root root 4096 Jun 21 18:49 /var/lib/program/subfolder
drwxr-xr-x 1 root root 4096 Jun 21 18:49 /var/lib/program
drwxr-xr-x 1 root root 4096 Jun 21 18:49 /var/lib
drwxr-xr-x 1 root root 4096 Jun 13 19:24 /var
#! /bin/bash
cur=""
IFS="/"
path=`pwd`
for dir in ${path:1}
do
cur=$cur/$dir
ls -lhd "$cur"
done
cur=$cur/$1
ls -lhd "$cur"
Terminal Session:
$ pwd
/tmp/dir_underscore/dir space/dir special #!)
$ ls
bash.sh test.txt
$ ./bash.sh test.txt
drwxrwxrwt 28 root root 36K Jun 21 22:45 /tmp
drwxr-xr-x 3 root root 4.0K Jun 21 22:27 /tmp/dir_underscore
drwxr-xr-x 3 root root 4.0K Jun 21 22:28 '/tmp/dir_underscore/dir space'
drwxr-xr-x 2 root root 4.0K Jun 21 22:54 '/tmp/dir_underscore/dir space/dir special #!)'
-rw-r--r-- 1 root root 0 Jun 21 22:29 '/tmp/dir_underscore/dir space/dir special #!)/test.txt'
This should possibly work:
pwd ; ls -lh ; while true ; do cd .. ; pwd ; ls -lh ; [[ "$PWD" == "/" ]] && break ; done
EDIT: I misunderstood the question at first. Try this:
(pwd ; ls -ldh ; while true ; do cd .. ; pwd ; ls -ldh ; [[ "$PWD" == "/" ]] &&
break ; done ; cd "$START")
EDIT2: fillipe's answer is probably the best, but here's my third and last attempt, which works on both files and directories:
magic_ls() {
fname="$1"
while true ; do
ls -lhd "$fname"
[[ "$fname" == "/" ]] && break ;
fname=$(dirname $(readlink -f "$fname"))
done
}
Just my 2 cents. My mac doesn't have the namei command (perhaps homebrew has a copy), but wanted to whip up a quick version that aligned the output in top-down order
#!/usr/bin/env bash
path="${1%/}"
DIRS=()
while test -n "$path"; do
DIRS=( "$path" "${DIRS[#]}" )
path="${path%/*}"
done
ls -ld "${DIRS[#]}"
Example output:
$ lspath $TMPDIR
lrwxr-xr-x# 1 root wheel 11 Oct 5 2018 /var -> private/var
drwxr-xr-x 7 root wheel 224 Jul 16 2020 /var/folders
drwxr-xr-x# 3 root wheel 96 Apr 5 2018 /var/folders/0c
drwxr-xr-x# 5 me staff 160 Apr 5 2018 /var/folders/0c/2_s_qxd11m3d1smzqdrs3qg40000gp
drwx------# 255 me staff 8160 Oct 7 09:18 /var/folders/0c/2_s_qxd11m3d1smzqdrs3qg40000gp/T

File permission displayed a lot question marks in docker container [duplicate]

This question already has answers here:
Strange file permission in docker container (question marks on permission bit and user bit)
(2 answers)
Closed 3 years ago.
I wrote a Dockerfile, the last contents are
RUN echo "root:root" | chpasswd
RUN echo "beakerx:beakerx" | chpasswd
RUN usermod -aG sudo beakerx
RUN echo beakerx | sudo -S chown -R beakerx:beakerx /home/beakerx/.local
RUN echo beakerx | sudo -S find /home/beakerx/.local -type d -exec chmod 755 {} \;
RUN echo beakerx | sudo -S find /home/beakerx/.local -type f -exec chmod 644 {} \;
RUN id
RUN ls -la /home/beakerx/.local
RUN ls -la /home/beakerx/.local/share
USER beakerx
RUN id
RUN ls -la /home/beakerx/.local
RUN ls -la /home/beakerx/.local/share
When I build this image, it gave me the following errors.
Step 17/29 : RUN echo "root:root" | chpasswd
---> Running in b07756b764ef
---> 11a182191463
Removing intermediate container b07756b764ef
Step 18/29 : RUN echo "beakerx:beakerx" | chpasswd
---> Running in 2f2bc836b1af
---> dee6ebdf5b9c
Removing intermediate container 2f2bc836b1af
Step 19/29 : RUN usermod -aG sudo beakerx
---> Running in 8a1ccfffd565
---> d7815406e070
Removing intermediate container 8a1ccfffd565
Step 20/29 : RUN echo beakerx | sudo -S chown -R beakerx:beakerx /home/beakerx/.local
---> Running in 19aebc73f517
---> a8cb84a563c5
Removing intermediate container 19aebc73f517
Step 21/29 : RUN echo beakerx | sudo -S find /home/beakerx/.local -type d -exec chmod 755 {} \;
---> Running in 7c2434fa279a
---> 5ce4b0b0e859
Removing intermediate container 7c2434fa279a
Step 22/29 : RUN echo beakerx | sudo -S find /home/beakerx/.local -type f -exec chmod 644 {} \;
---> Running in 5f57457f1fe5
---> 1bb42b3ef8f3
Removing intermediate container 5f57457f1fe5
Step 23/29 : RUN id
---> Running in 101209499f50
uid=0(root) gid=0(root) groups=0(root)
---> e45945b090ab
Removing intermediate container 101209499f50
Step 24/29 : RUN ls -la /home/beakerx/.local
---> Running in d337b58c1571
total 12
drwxr-xr-x 6 beakerx beakerx 4096 Sep 7 01:30 .
drwxr-xr-x 25 beakerx beakerx 4096 Sep 7 01:30 ..
drwxr-xr-x 6 beakerx beakerx 4096 Sep 7 01:30 share
---> 7fd474369e15
Removing intermediate container d337b58c1571
Step 25/29 : RUN ls -la /home/beakerx/.local/share
---> Running in e05cd55aaae6
total 12
drwxr-xr-x 6 beakerx beakerx 4096 Sep 7 01:30 .
drwxr-xr-x 6 beakerx beakerx 4096 Sep 7 01:30 ..
drwxr-xr-x 6 beakerx beakerx 4096 Sep 7 01:30 jupyter
---> 03191c2d9fc8
Removing intermediate container e05cd55aaae6
Step 26/29 : USER beakerx
---> Running in 40b2d522ea0f
---> 604503b2152b
Removing intermediate container 40b2d522ea0f
Step 27/29 : RUN id
---> Running in e7b8ed6a1165
uid=1000(beakerx) gid=1000(beakerx) groups=1000(beakerx),27(sudo)
---> 5987e9d9f0bb
Removing intermediate container e7b8ed6a1165
Step 28/29 : RUN ls -la /home/beakerx/.local
---> Running in 4c65bd4a383e
ls: cannot access '/home/beakerx/.local/share': Permission denied
total 8
drwxr-xr-x 6 beakerx beakerx 4096 Sep 7 01:30 .
drwxr-xr-x 25 beakerx beakerx 4096 Sep 7 01:30 ..
d????????? ? ? ? ? ? share
ERROR: Service 'beakerx-cling-prebuild' failed to build: The command '/bin/sh -c ls -la /home/beakerx/.local' returned a non-zero code: 1
That's quite strange, I can see the right permission using root, but a lot of question marks using other users. When I removed these debugging code and run this docker image, it gave me PermissionError: [Errno 13] Permission denied: '/home/beakerx/.local/share/jupyter/runtime' errors.
I have searched a lot on the Internet, but couldn't found some helpful info about this.
This is a very weird bug in older docker versions. It happens if the first user that access the directory is non-root. Just change the order of the commands to access the dir as user.
Run something like ls /home/beakerx/, before issuing USER beakerx.
It worked for me.

chmod doesn't work in mounted partition

I have this file in my mounted partition
/path/to/hardDiskDrive/$ ls -l
-rw------- 1 arash arash 92827804 Jun 15 17:35 qt-creator-opensource-linux-x86_64-4.0.2.run
and then try to chmod it but nothing happens even with sudo
/path/to/hardDiskDrive/$ chmod +x qt-creator-opensource-linux-x86_64-4.0.2.run
/path/to/hardDiskDrive/$ ls -l
-rw------- 1 arash arash 92827804 Jun 15 17:35 qt-creator-opensource-linux-x86_64-4.0.2.run
but when i copy it to my Linux home directory everything works fine ..
What is the resne of this ?!!
~/Desktop $ ls -l
-rw------- 1 arash arash 92827804 Jun 15 17:35 qt-creator-opensource-linux-x86_64-4.0.2.run
~/Desktop $ chmod +x qt-creator-opensource-linux-x86_64-4.0.2.run
~/Desktop $ ls -l
-rwx--x--x 1 arash arash 92827804 Jun 15 17:35 qt-creator-opensource-linux-x86
What is the reason of this?!! and How can i run this file from original place in Hard Drive?
thanks

How to remove and re-create an existing symlink in one single command?

I have a symlink for my live server called current and I have releases in the releases directory, i.e current -> releases/2012-05-08_15-13
If I want to update the symlink of my current directory, I have to unlink/rm it and re ln -s it.
My question is: How can I remove the symlink and update it to the latest release in one step.
The form of ln is
ln -sf sourcefile targetlink
Try
ln -sf releases/2012-05-08_15-13 current
to remove the current and create the new link.
If you want to do it in a single command, do as #hughw suggests and run ln -sf.
If you want to replace the symlink atomically (ie. so that there's no point in time where the symlink doesn't exist) create a new symlink, then mv it over the old one.
As suggested by ToddR, here is the only answer that actually works on maybe most flavours of Linux - definately Ubuntu - which uses ln from coreutils package). Let me prove it to you.
matthewh#xen:~$ mkdir -p releases/dirA
matthewh#xen:~$ mkdir -p releases/dirB
matthewh#xen:~$ ln -s releases/dirA
matthewh#xen:~$ ls -l dirA
lrwxrwxrwx 1 matthewh matthewh 13 Apr 7 09:58 dirA -> releases/dirA
matthewh#xen:~$ ln -sf releases/dirB
matthewh#xen:~$ rm dirA
matthewh#xen:~$ ln -s releases/dirA current
matthewh#xen:~$ ln -sf releases/dirB current
matthewh#xen:~$ ls -l current
lrwxrwxrwx 1 matthewh matthewh 13 Apr 7 09:59 current -> releases/dirA <--- DOESN'T WORK!
matthewh#xen:~$ ln -sfn releases/dirB current <--- WORKS!
matthewh#xen:~$ ls -l current
lrwxrwxrwx 1 matthewh matthewh 13 Apr 7 09:59 current -> releases/dirB
So the correct method on Linux is:
ln -sfn source target
-n, --no-dereference
treat LINK_NAME as a normal file if it is a symbolic link to a directory
This is essential, if you do not use -n switch you will end up with a symlink inside source directory named "target".
In my examples,
matthewh#xen:~$ ls -l releases/dirA/
total 0
lrwxrwxrwx 1 matthewh matthewh 13 Apr 7 10:03 dirB -> releases/dirB
correct answer:
ln -s new current_tmp && mv -Tf current_tmp current
Move is atomic operation.
Don't use 'ln -snf'.
strace 'ln -snf' shows two system calls unlink + symlink.
This example clears the use of -sfn switch:
drwxr-xr-x. 10 root root 4096 Aug 25 18:24 .
dr-xr-xr-x. 25 root root 4096 Aug 19 10:32 ..
lrwxrwxrwx. 1 wildfly wildfly 25 Aug 25 18:15 wildfly -> /opt/wildfly-8.2.0.Final/
drwxr-xr-x. 10 wildfly wildfly 4096 Aug 25 18:28 wildfly-8.2.0.Final
link to link
| |
[gecloud#ip-10-227-224-45 opt]$ sudo ln -sfn wildfly-8.2.0.Final /opt/wildfly
[gecloud#ip-10-227-224-45 opt]$ ls -la
total 115540
drwxr-xr-x. 10 root root 4096 Aug 25 18:34 .
dr-xr-xr-x. 25 root root 4096 Aug 19 10:32 ..
lrwxrwxrwx. 1 root root 19 Aug 25 18:34 wildfly -> wildfly-8.2.0.Final
drwxr-xr-x. 10 wildfly wildfly 4096 Aug 25 18:28 wildfly-8.2.0.Final

Resources