Error while executing command inside script [duplicate] - bash

This question already has answers here:
Why bash alias doesn't work in scripts? [duplicate]
(3 answers)
Closed 4 years ago.
On ubuntu 18.10 I've problem with a simple script.
If I execute this command directly from shell it works:
drush -y rsync #d8.live:web/sites/default/files #self:sites/default --delete -vv
If I create a .sh script with:
#!/bin/bash
drush -y rsync #d8.live:web/sites/default/files #self:sites/default --delete -vv
The script doesn't work and the drush command returns me an error:
The "--delete" option does not exist.
The command and the script are running from the same directory and the same user.
Where is the problem?
PS: "drush" is a wrapper that executes a docker-compose command
[EDIT]
$ type -a drush
drush ha "drush --strict=0" come alias
drush è /usr/local/bin/drush
$ cat /usr/local/bin/drush
#!/bin/bash
cd $PWD
docker-compose -p example exec --user 82 php drush $#

Aliases don't get expanded in scripts. If you want the script to include --strict=0 in the command line, you have to say so explicitly in the script.

As mentioned here:
$ type -a drush
drush ha "drush --strict=0" come alias
drush è /usr/local/bin/drush
the drush command is within your PATH environmental variable.
Now please make sure that /usr/local/bin folder is part of your `PATH variable, e.g. by:
$ tr : "\n" <<<$PATH | grep usr.local.bin
/usr/local/bin

Related

Bash Script with docker commands not running via Crontab

hey guys not sure what I am doing wrong here, but was hoping for some help.
I have a bash script with the following.
#!/bin/bash
docker exec -t wekan-db bash -c "scripts/wekandb_backup.sh"
docker exec -t wekan-db bash -c "rm -r /dump/*; cp -r /mongodb_backup/ /dump/mongodb_backup"
docker cp wekan-db:/dump /home/ikadmin/codes/backup/wekan/$(date +%Y-%m-%d)
Everything executes correctly when I run the bash script from the terminal.
However when I try to run it via crontab -e it does not work. Logs do show crontab trying to run it.
Just in case the bash script is currently set as 777 as well.
Any help would be appreciated
EDIT: crontab command
19 8 * * * /bin/bash /home/ikadmin/codes/scripts/backup-wekan-docker.sh

executing shell command in docker composer gives me error

I'm trying to execute shell command in docker-compose.yml. Code is:
command: bash -c mkdir /opt/wa/usr/install_templates
When I do:
sudo docker-compose up serviceA
it gives me :
serviceA | mkdir: missing operand
When you use bash -c, it runs the first string after the -c flag. See this SO answer for more information. Docker is reading your command bash -c mkdir /path/ and your bash command is just running mkdir in a bash subshell, causing that error.
You don't need to put bash -c before your commands in a docker-compose file. The Docker engine will handle running it in a shell for you and you can simply write the command you want to be run. I'd suggest replacing your command with this:
command: mkdir /opt/wa/usr/install_templates
Alternatively, you could try putting the entire command into a string if you want to force the command to be run in bash:
command: bash -c "mkdir /opt/wa/usr/install_templates"

bash: C:/Program: No such file or directory

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.

How to check if command exists for a user?

I install Pip for a user (not system wide) and I would like to check that pip is installed for that user in my script that I run with sudo: sudo ./script.sh
I know to check for a command with command -v pip3 and that works when I enter it in the shell as the user.
But how can I check it in my script?
command -v pip3 exit code is 1 because I am root (because of sudo).
su -c "command -v pip3" "$SUDO_USER" has exit code 1.
sudo -u "$SUDO_USER" command -v pip3 says "command: command not found"
The simplest is
sudo -u "$SUDO_USER" -i command -v pip3
The -i option causes sudo to pass the supplied command line to the user's configured shell using its -c option, instead of trying to execute the command directly. That's necessary because command is a shell built-in; it doesn't exist as a stand-alone executable. (The -i options runs a "login" shell. There is also the -s option which runs a non-login shell. See below.)
If you want to specify a shell explicitly you could do so instead:
sudo -u "$SUDO_USER" /bin/sh -lc "command -v pip3"
Again, a login shell is forced, here by using the -l option.
As a safety feature, sudo normally resets the $PATH to a "safe" value before executing the shell (or the single command). That value will not have any of the modifications made in the /etc/profile and ~/.profile startup scripts, and without those modifications -- which add one or more user-specific directories to the path -- the shell will not find software such as pip3 which has been installed for individual users.
use following command by replacing $USER with the specific user name.
sudo -H -u $USER bash -c 'command -v pip3'
similarly, you can run any command as another user
syntax : sudo -H -u $USER bash -c 'INSERT_COMMAND_HERE'

Bash script gets printed instead of being executed

This question is similar to this one: https://serverfault.com/questions/342697/prevent-sudo-apt-get-etc-from-swallowing-pasted-input-to-stdin but the answer is not satisfying (appending && to each line of bash script is not elegant) and does not explain why some users can paste/execute multiple subsequent apt-get install -y commands and others can't because stdout is swollen by the next command.
I have a script my_script.sh:
sudo apt-get install -y graphicsmagick
sudo apt-get install -y libgraphicsmagick++1-dev
...
It can have only two lines or more of sudo apt-get install stuff. The libraries (graphicsmagick, etc.) doesn't matter, it can be any library.
When I copy this script and paste it's contents to bash or just execute it like this:
cat my_script.sh | sudo -i bash
then for some reason only the first line (graphicsmagick) gets executed and the rest is just printed to the console. It happens only with sudo apt-get install -y, other scripts, which doesn't contain this command behave normally.
If I change bash to sh (which is dash) I get expected behaviour:
cat my_script.sh | sudo -i sh
Can you explain why this happens?
When answering, can you please avoid this questions/comments:
Why are you doing it this way?
Piping to your bash is not safe
Some other aspects are not safe or hackish
I just want to know why bash doesn't work as I would expect and sh does.
PS. I'm using Ubuntu 14.04, sh is dash as you can see here:
vagrant#vagrant-ubuntu-trusty-64:/tmp$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Feb 19 2014 /bin/sh -> dash
Bash and dash simply behave different when using -i flag.
Bash always goes to interactive mode even when stdin is not a terminal.
Dash on the other hand will not go into interactive mode, even with -i flag.
Probably need the -s option
If the -s option is present, or if no arguments remain after option
processing, then commands are read from the standard input. This option allows
the positional parameters to be set when invoking an interactive shell.
Bash man page
curl -s http://foo.com/bar.sh | sudo -i bash -s
Example

Resources