The command which on line 4 on the script below seems to have an issue, intellij says
which is non-standard. Use builtin 'command -v' instead
Since which psql seems like it is not working it automatically affects line 12 and 13.
While investigating i removed line 4 then the script executed line 6 to 10 which succefully created a docker file(pg-docker) however i also need the schema.sql (line 12) and data.sql (13) to be executed. Is there an alternative command for which command(line 4)
Below is my bash Script:
#!/usr/bin/env bash
set -euo pipefail
which psql > /dev/null || (echo "Please ensure that postgres client is in your PATH" && exit 1)
mkdir -p $HOME/docker/volumes/postgres
rm -rf $HOME/docker/volumes/postgres/data
docker run --rm --name pg-docker -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=dev -d -p 432:5432 -v $HOME/docker/volumes/postgres:/var/lib/postgresql postgres
sleep 3
export PGPASSWORD=postgres
psql -U postgres -d dev -h localhost -f schema.sql
psql -U postgres -d dev -h localhost -f data.sql
I get the below on the problems on Intellij
line 4 complains about which command
line 6,7 and 9 complains about $HOME
line 11 complains about PGPASSWORD
which is used to find and show the full path of a command (in your script it is only used to make sure the command psql is there).
IntelliJ or probably better the defined linter for (bash) scripts suggest not to rely on an separate whichcommand but just use the builtin bash-function command -v so the line 4 would read
command -v psql > /dev/null || (echo "Please ensure that postgres client is in your PATH" && exit 1)
That said - it's most likely not your real problem. You need the PostgreSQL Client psql installed and in your PATH variable to run the commands in line 12 and 13. Exactly that's what you're checking in line 4 - regardless of using which or command -v.
How to install the psql command depends on your OS.
Related
I am new to Docker, Debezium, Bash, and Kafka. I am attempting to run the Debezium tutorial/example for MSSQL Server on Windows 10 here:
https://github.com/debezium/debezium-examples/blob/master/tutorial/README.md#using-sql-server
I am able to start the topology, per step one. However, when I go to step two and execute the following command:
cat debezium-sqlserver-init/inventory.sql | docker exec -i tutorial_sqlserver_1 bash -c '/opt/mssql-tools/bin/sqlcmd -U sa -P $SA_PASSWORD'
I get the following error:
bash: C:/Program: No such file or directory
I do not have the foggiest idea why it would even drag C:/Program in to this. I do not see it in the command nor do I see it in the *.sql file. Does anyone know why this is happening and what the fix is?
Note 1: I am already in the current directory where this command should be runnable and there are no spaces in the folder/file path
Note 2: I am running the commands in Git Bash
When using set -x to log how the command is run, there's still no C:/Program anywhere in it, as can be seen by the following log:
$ cat debezium-sqlserver-init/inventory.sql | docker exec -i tutorial_sqlserver_1 bash -c '/opt/mssql-tools/bin/sqlcmd -U sa -P $SA_PASSWORD'
+ cat debezium-sqlserver-init/inventory.sql
+ docker exec -i tutorial_sqlserver_1 bash -c '/opt/mssql-tools/bin/sqlcmd -U sa -P $SA_PASSWORD'
bash: C:/Program: No such file or directory
I had a similar problem yesterday, the solution was adding a backslash before the absolute path, like :
cat debezium-sqlserver-init/inventory.sql | docker exec -i tutorial_sqlserver_1 bash -c '\/opt/mssql-tools/bin/sqlcmd -U sa -P $SA_PASSWORD'
\/opt/mssql-tools/bin/sqlcmd prevents conversion to Windows path.
I have a bash file should bring the postgres docker container online and then run a .sql file to create the databases. But it's throwing the error.
psql: error: provision-db.sql: No such file or directory
I have checked the path and the file exists at the same level of this bash script. Following is the content of my bash file.
#!/usr/bin/env bash
docker-compose up -d db
# Ensure the Postgres server is online and usable
until docker exec -i boohoo.postgres pg_isready --host="${POSTGRES_HOST}" --username="${POSTGRES_USER}"
do
echo "."
sleep 1
done
docker exec -i boohoo.postgres psql -h "${POSTGRES_HOST}" -U "${POSTGRES_USER}" -a -q -f provision-db.sql
And this is the provision-db.sql file.
DROP DATABASE "boo-hoo";
CREATE DATABASE "boo-hoo";
GRANT ALL PRIVILEGES ON DATABASE "boo-hoo" TO postgres;
This is the part of docker-compose.yml
version: '3.3'
services:
db:
container_name: boohoo.postgres
hostname: postgres.boohoo
image: postgres
ports:
- "15432:5432"
environment:
POSTGRES_USER: "postgres"
POSTGRES_PASSWORD: "postgres"
The short version
This works
cat provision-db.sql | docker exec -i boohoo.postgres bash -c 'psql -U ${POSTGRES_USER} -w -a -q -f -'
The long version
multiple things here
1) why does following command not find the provision-db.sql?
docker exec -i boohoo.postgres psql -h "${POSTGRES_HOST}" -U "${POSTGRES_USER}" -a -q -f provision-db.sql
because the provision-db.sql is on your host and not in your container. Therefore, when you execute the psql command inside the container it can not find the file
2) Why didn't my first solution work?
cat provision-db.sql | docker exec -i boohoo.postgres psql -h "${POSTGRES_HOST}" -U "${POSTGRES_USER}" -a -q -f - should do the trick asuming provision-db.sql
That is due to the fact, that the variables ${POSTGRES_USER} and ${POSTGRES_PASSWORD} get evaluated on your host machine and I guess they are not set there. In addition, I forgot to specify the -w flag to avoid the password prompt
3) Why does that work?
cat provision-db.sql | docker exec -i boohoo.postgres bash -c 'psql -U ${POSTGRES_USER} -w -a -q -f -'
Well, let's go through it step by step.
First, we print the content of provision-db.sql, which resides on the host machine to stdout and pipe it to the next command via |.
docker-exec executes a command in the container specified (boohoo.postgres). By specifying the -i flag we allow the stdin from your host to go to stdin in the container <- that's important.
In the container, we execute bash -c which is just a wrapper to avoid evaluating the bash variables on the host. We want the variables from the container and by putting it into single quotes we can do that.
docker-exec boohoo.postgres bash -c "echo $POSTGRES_USER"
evaluates the host env variable named POSTGRES_USER.
docker-exec boohoo.postgres bash -c "echo $POSTGRES_USER"
evaluates the container env variable named POSTGRES_USER.
Next we just have to get our postgres command in order.
psql -U ${POSTGRES_USER} -w -a -q -f -
-U specifies the user
-w does not ask for password
-q do it quietly
-f - process whatever you get from stdin
-f is an option for psql and not for docker exec, and psql is running inside the container, so it can only access the file if it is inside the container as well.
I have a kiosk that shuts down every day using rtcwake, and this uses root user. I've used && to execute the boot script after rtcwake completes, however it then starts the browser as root causing problems.
This is the command I use:
echo debian | sudo -S rtcwake -m mem -u -t $(date +%s -d '3 days 7:45') && sudo -u debian -i bash $HOME/kiosk/bin/startup.sh &.
The sudo command does work to some extent. It calls the debian user, and executes the correct script, however, it still screws up my chromium preferences.
Here is the startup script:
echo debian | sudo -S hwclock -w
export HOME=/home/debian
#log boot time
echo "Booting at" $(date) >> $HOME/kiosk/bin/logs/boot.log
#echo debian | sudo -S service connman restart
echo debian | sudo -S at 15:30 -f $HOME/kiosk/bin/shutdown.sh
crontab -u debian crontab.txt
bash $HOME/git.sh
#sudo -i -u debian
#start kiosk
export DISPLAY=:0
chromium-browser --kiosk --disable-gpu
http://localhost/kiosk/Client/main.html &
#update ip
bash /home/debian/git.sh &
I'm wondering what could be causing chrome to be executed as root. I have no idea what is going wrong.
If you execute a command with sudo it will not change environment variables like $HOME. Since per user settings are stored in $HOME, this affects the executed program if it needs such configuration files. Check this for example:
sudo -u debian bash -c 'echo $HOME'
It will print the home folder of the calling user, not the home folder of the user specified trough -u. The sudo command supports the -H command line option to handle this, however if it works depends on the security police in use.
As a solution you can use the su command instead of sudo in this case:
... && su debian -c chromium
Since su itself is executed by root you won't be asked for the password.
You must enter a password to log into a new user shell.
The command needs to be modified as follows:
echo debian | sudo -S rtcwake -m mem -u -t $(date +%s -d '3 days 7:45') && echo debian | sudo -S -u debian -i bash $HOME/kiosk/bin/startup.sh &
This avoids needing a password to log in as normal Debian user, and executes the script.
I have set the PATH environment and then run psql on command prompt and then whatever command I write nothing happens, it doesn't throw any error message too.
even very basic commands as;
psql -l
pg_dump -U {user-name} {source_db} -f {dumpfilename.sql}
Do you have any idea?
You have to finish each command with a semicolon (;). Until you do so, psql thinks you're still writing the same (multi-line) command.
Also, psql -l and pg_dump -U {user-name} {source_db} -f {dumpfilename.sql} are not psql commands. These should be ran from your shell (without the semicolons), not from the psql terminal.
I want to run 2 different scripts from a single master shell script.
The first one uses the following command "rosh -n -l abcd" (It will log me in to the server with the user abcd and on the same shell I need to run the other script#2 and script#3 ...etc.)
Script#2- From there I need to change user using su - xyz and provide a password (it is fine if I can hardcode this in the file) (Script name is logintoServer)
Script#3- Run some script in the same shell to verify start of stop of server...
I have done the following but failed
I have one script which has rosh -n <servername> -l abcd /bin/sh -c "su - xyz" (I have to run this command in the same shell)
The below are the errors:
I am getting error while executing "standard in must be a tty"
I have tried to create 2 different scripts and run, but the problem is once the first script is run it does not run the 2nd script till I exit the script. (I need to run the 2nd script from the sub-shell created by the 1st script....)
I don't have rosh and I don't have a man page for rosh but a similar problem exists with ssh:
ssh localhost /bin/bash -c 'echo x' # (prints nothing)
ssh localhost "/bin/bash -c 'echo x'" # x
ssh localhost "/bin/bash -c 'tty'" # not a tty
ssh -t localhost "/bin/bash -c 'tty'" # /dev/pts/12\nConnection to localhost closed.
ssh localhost "/bin/bash -c 'su - $USER'" # su: must be run from a terminal
ssh -t localhost "/bin/bash -c 'su - $USER'"
the last asked for a password and then gave me a shell, so that would be 2 of 3 steps.
so one idea is to see if rosh has the -t option, too and the other is to enclose /bin/bash... with quotes, too (will require some escaping for the 3rd level).
What does rosh say with equivalent commands?
UPDATE
latest state:
rosh -n $host -l abcd -t "/bin/sh -c 'su - $user'"
Next I would save one step by saying /bin/su - xyz instead /bin/sh -c 'su - xyz', then you can use single quotes later, e.g.
rosh -n $host -l abcd -t "/bin/su - $user -c 'echo $PATH'"
this should print $PATH as seen by the echo command. Apparently it doesn't contain java. try man su, which java, man which.
su ... -c cmd runs cmd with the shell specified in /etc/passwd, so say </etc/passwd grep $user on the remote machine to find out which shell is used. if it's bash you can change $PATH in .bashrc or so, for other shells I don't know exactly.
Or specify an absolute path when launching java.
regarding password: with ssh I managed to use private key / public key and ssh-agent. For rosh I don't know if that works, too.