Not able to run shell script in busybox without mounting procfs - linux

I am trying to run a shell script in busybox rootfs with linux kernel version 4.4.4. Test script tries to mount procfs.
#!/bin/sh
mount -t proc none /proc
I can run this script with sh test.sh, but if I tries to run using ./test.sh, it says /bin/sh test.sh not found. Strange thing is after mounting procfs manually
mount -t proc none /proc
I can run ./test.sh. For busybox I am using default config with static enabled.

Related

How to mount /proc in Docker Container

Why can't I mount the /proc device from the container during the build process?
If I run docker build -t test . with this Dockerfile:
FROM debian:stable-slim
RUN bash -c 'ls {/proc,/dev,/sys}'
I can see that all special devices are populated. But if I try this Dockerfile:
FROM debian:stable-slim
RUN bash -c 'ls {/proc,/dev,/sys}'
RUN mount --bind /proc /mnt
I get the following error:
mount: /mnt: permission denied.
The command '/bin/sh -c mount --bind /proc /mnt' returned a non-zero code: 32
I know it's possible to use --privileged mode in docker run, but my goal is not to access the host's /proc but to just mount the /proc device from container in a file system that I'm generating inside the container with debootstrap. So that I can install some packages, specifically default-jre.
My Docker Version: 20.10.8
EDIT
My goal is to create a custom live-cd like here, so I can't use the container's base OS.

Gio Mount Returns Different Outputs

I'm trying to make python script for mounting using Gio Module, however when i add my script to crontab or run it as a service, i only get filesystem root:
In shell:
gio mount -l
returns every mountable drive and volume,
however, when i run:
sudo gio mount -l
or
sudo -u myuser gio mount -l
i only get Filesystem root and floppy.
The difference i realized is,
sudo, or my script auto ran by system returns the volumes with type "GUnixVolume",
and just "gio mount -l" returns type GProxyDrive.
So what is the difference, and how can i detect external drives when my script is ran by system?

docker exec with standard output logged in a file inside the docker container

I am currently running a cronjob from a host machine (Linux Redhat) executing a script in a docker container. The problem I have is that when I redirect the standard output to a file with path inside the docker container, the cronjob threw an exception basically saying that the path of the log file cannot be found. But if I change the output log file path to be a path that is on the host machine, it works fine.
Below does not work
0 9 * * 1-5 sudo docker exec -i /path/in/docker/container/script.sh > /path/in/docker/container/script.shout
But this one works
0 9 * * 1-5 sudo docker exec -i /path/in/docker/container/script.sh > /path/in/host/script.shout
How do I get the first cronjob working so I can have the output file in the docker container using the path in the docker container?
I don't want to run the cronjob as root and that's why I need sudo before docker exec. Please note, only root has access to the docker volume path in the host machine, which is why I can't use the docker volume path either.
Cron runs your command with a shell, so the output redirect is handled by the shell running on your host, not inside your container. To get shell commands like this to run inside the container, you need to run a shell as your docker command, and escape or quote your any of those shell options to avoid having them interpreted until you are inside the container. E.g.
0 9 * * 1-5 sudo docker exec -i container_name /bin/sh -c \
"/path/in/docker/container/script.sh > /path/in/docker/container/script.shout"
I would rather try and path the redirection path as a parameter to the script (so remove the '>'), and make the script itself redirect its output to that parameter file.
Since the script is executed in a docker container, it would see that path (as opposed to the cron job, which sees by default host paths)
We can use bach -c and put the redirect command between double quotes as in this command:
docker exec ${CONTAINER_ID} bash -c "./path/in/container/script.sh > /path/in/container/out"
And we have to be sure /path/in/container/script.sh is an executable file either by using this command from the container:
chmod +x /path/in/container/script.sh
or by using this command from the host machine:
docker exec ${CONTAINER_ID} chmod +x /path/in/container/script.sh
You can use tee: a program that reads stdin and writes the same to both stdout AND the file specified as an arg.
echo 'foo' | tee file.txt
will write the text 'foo' in file.txt
Your desired command becomes:
0 9 * * 1-5 sudo docker exec -i /path/in/docker/container/script.sh | tee /path/in/docker/container/script.shout
The drawback is that you also dump to stdout.
You may check this SO question for further possibilities and workarounds.

Shell script to mount windows network location in linux machine

I have two questions here. I am able to mount a windows network path in my Ubuntu machine by doing following:
sudo mount -t cifs -o username=user \\\\my_windows\\test /net/loc
All the files and folders present in Windows machine is now available in Ubuntu machine with path '/net/loc'.
Here are my doubts:
I can see all files of windows in linux path. Is it possible to create files/folders in Linux path(the mount path where windows path is mounted) and it will be reflected in Windows machine? I am not able to write in Linux machine where windows network location is mounted. It throws me error "Can't open file for writing".
I am trying to write a shell script (a ksh file) which will mount the windows network path. I wrote the below mount command in my file but this command prompts for password. Is there any way, I can write the command in shell script that it will not ask me for password and I can pass it as either as a parameter or some other mechanism?
mount -t cifs -o username=user \\my_windows\test /net/loc
Thank you
Password can be passed as below
sudo mount -t cifs -o username=${USER},password=${PASSWORD},uid=,gid= //server-address/folder /mount/path/on/ubuntu
And with root access I am able to write in Linux path.
More information is here https://unix.stackexchange.com/questions/68079/mount-cifs-network-drive-write-permissions-and-chown

What is the purpose of the "-i" and "-t" options for the "docker exec" command?

To be honest, I have always been confused about docker exec -it …, docker exec -i … and docker exec -t …, so I decide to do a test:
docker exec -it …:
# docker exec -it 115c89122e72 bash
root#115c89122e72:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
It works normally.
docker exec -i …:
# docker exec -i 115c89122e72 bash
^C
The command hangs and I have to use Ctl + c to interrupt it.
docker exec -t …:
# docker exec -t 115c89122e72 bash
root#115c89122e72:/# ls
^C
It enters the container successfully but hangs on executing the first command.
So it seems there is no point in having the docker exec -i … and docker exec -t … commands. Could anyone elaborate on why there exist -i and -t options for the docker exec command?
-i, --interactive keeps STDIN open even if not attached, which you need if you want to type any command at all.
-t, --tty Allocates a pseudo-TTY, a pseudo terminal which connects a user's "terminal" with stdin and stdout. (See container/container.go)
If you do an echo, only -t is needed.
But for an interactive session where you enter inputs, you need -i.
Since -i keeps stdin open, it is also used in order to pipe input to a detached docker container. That would work even with -d (detach).
See "When would I use --interactive without --tty in a Docker container?":
$ echo hello | docker run -i busybox cat
hello
-i keeps STDIN open even if not attached, what is the status of STDOUT in this case?
It is, for docker exec, the one set by docker run.
But, regarding docker exec, there is a current issue (issue 8755: Docker tty is not a tty with docker exec
unfortunately your discovery only amounts to a difference between the behaviour of tty in centos6 vs ubuntu:14.04. There is still not a functional tty inside the exec - just do ls -la /proc/self/fd/0 and see that it's a broken link pointing to a pts which doesn't exist.
the actual bug we're dealing with is that certain standard libraries assume that the symlinks in /proc/self/fds/ must be valid symlinks
The problem is that the tty is created outside on the host and there is no reference to it in the container like how /dev/console is setup in the primary container.
One options to fix this would be allocate and bind mount the devpts from the host in to the containers.
Note (Q4 2017): this should been fixed by now (docker 17.06-ce).
See PR 33007.
That PR now allows (since 17.06):
zacharys-pro:dev razic$ docker run --rm -t -d ubuntu bash
83c292c8e2d13d1b1a8b34680f3fb95c2b2b3fef71d4ce2b6e12c954ae50965a
zacharys-pro:dev razic$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
83c292c8e2d1 ubuntu "bash" 2 seconds ago Up 1 second xenodochial_bardeen
zacharys-pro:dev razic$ docker exec -ti xenodochial_bardeen tty
/dev/pts/1
(before 17.06, tty was returning "not a tty")

Resources