Old version of script is run unless invoked with "sh scriptname" - bash

I'm making a small edit to a shell script I use to mask password inputs like so:
#!/bin/bash
printf "Enter login and press [ENTER]\n"
read user
printf "Enter password and press [ENTER]\n"
read -s -p pass
With the read -s -p pass being the updated part. For some reason I'm not seeing the changes when I run it normally by entering script.sh into the command line but I do see the changes when I run sh script.sh. I've tried opening new terminal windows, and have run it in both ITerm and the default Mac terminal. I'm far from a scripting master, does anyone know why I'm not seeing the changes without the prefix?

Use a full or relative path to the script to make sure you're running what you think you're running.
If you are running it as simply script.sh then the shell will PATH environment variable lookup to locate it. To see which script.sh bash would be using in that case, run type script.sh.
Relative Path
./script.sh
Full Path
/path/to/my/script.sh

Related

sudo: command not found while using plink

Hi i have created a batch file (run.bat) that after execution connects me to UNIX server with help of plink. But issue starts from this point i have to execute a script after connection to my server the script contains a command sudo -l. After the execution i get the error as mentioned in subject can anyone help me on this issue ??
Batch File-:
"C:\Program Files\PuTTY" plink -ssh -pw Tos#12Ts w44dvftyw#caa1607UX009.wvd.abcd.net /opt/sieb/w44dvftyw/run.sh
Script file(run.sh) -:
#!/bin/bash
sudo -l
It says
sudo: command not found
But when i run my script normally on UNIX server it runs with no issues. What am i missing here to make it work this way please help.
Scripts such as ~/.profile or ~/.bash_profile responsible for setting up the current user's PATH are run only on login shells.
Running sh -c 'somescript' (as performed by ssh host 'somescript') is neither a login shell, nor an interactive shell; thus, it does not gain the benefit of such scripts.
This means that additions to the PATH (in your case, /usr/local/bin) may not be present with commands run in this way.
Among your options:
Pass the PATH you want as part of the command to remotely run. This might look like:
plink -ssh user#host "PATH=/bin:/usr/bin:/usr/local/bin /opt/sieb/w44dvftyw/run.sh"
Embed a working value in the script you're running:
#!/bin/bash
PATH=/bin:/usr/bin:/usr/local/bin
# ...put the rest of your script here.

Sending Bash Aliases to detached screen sessions

I'm on a Linux machine using screen, and I'm attempting to write a (fairly portable) function which runs a bash function in a new, detached screen session which automatically closes upon completion. I've had some success, but I noticed the following behavior:
If I include the definition of mail_submit() in my ~/.bashrc file, I can run
mail_submit foo
in the terminal, and also I can access the alias in a new screen session:
screen -S test
mail_submit foo
However, the following command does not work:
screen -d -m -S test sh -c 'mail_submit foo'
presumably because sh -c starts a fresh shell that has no knowledge of my ~/.bashrc profile. So, I can use the following fix:
screen -d -m -S test sh -c 'source ~/.bashrc; mail_submit foo'
which does work.
But if I want to wrap this functionality up into a bash alias (which is my ultimate goal here), this will cause a weird self-referential situation.
Question: What is an easy way to either have sh -c know the location of my ~/.bashrc profile, or use a variant of sourcing the file and creating an alias?
EDIT: I could save the shell script in my home directory, and create an alias which runs
screen -d -m -S test bash -c '~/mail_submit.sh $1'
but I'd still be curious to hear other possible fixes.
A default ~/.bashrc contains this ([[ "$-" != *i* ]] && return) little piece of code on top of it (or somewhere else in the upper part). This line will prevent the ~/.bashrc from beeing sourced if the bash shell doesn't run in interactive mode.
You could:
Remove this line
Create a new file which will only contain the alias you need and source that
Create a little bash script instead of an alias and run that
Do you mean screen -d -m -S test bash -c 'mail_submit foo'?
It looks like you're trying to run the command with the shell (sh), and not the bourne again shell (bash), which is the shell interpreter which actually reads the ~/.bashrc profile.
Edit: The .bashrc file is not being sourced by default because screen does not create the bash process as a login shell, which is when the .bashrc file is read. Creating a .screenrc file with the line defshell -bash will create the bash process as a login shell instead, which will then call the .bashrc file.

Problems using scala to remotely issue commands via ssh

I have a problem with scala when I want to create a directory remotely via ssh.
ssh commands via scala, such as date or ls, work fine.
However, when I run e.g
"ssh user#Main.local 'mkdir Desktop/test'".!
I get: bash: mkdir Desktop/test: No such file or directory
res7: Int = 127
When I copy-paste the command into my shell it executes without any problems.
Does anybody know what is going on??
EDIT:
I found this post : sbt (Scala) via SSH results in command not found, but works if I do it myself
However, the only thing I could take away from it is to use the full path for the directory to be created. However, it still does not work :(
Thanks!
ssh doesn't require that you pass the entire command line you want to run as a single argument. You're allowed to pass it multiple arguments, one for the command you want to run, and more for any arguments you want to pass that command.
So, this should work just fine, without the single quotes:
"ssh user#Main.local mkdir Desktop/test"
This shows how to get the same error message in an ordinary bash shell, without involving ssh or Scala:
bash-3.2$ ls -d Desktop
Desktop
bash-3.2$ 'mkdir Desktop/test'
bash: mkdir Desktop/test: No such file or directory
bash-3.2$ mkdir Desktop/test
bash-3.2$
For your amusement, note also:
bash-3.2$ mkdir 'mkdir Desktop'
bash-3.2$ echo echo foo > 'mkdir Desktop'/test
bash-3.2$ chmod +x 'mkdir Desktop'/test
bash-3.2$ 'mkdir Desktop/test'
foo
UPDATE:
Note that both of these work too:
Process(Seq("ssh", "user#Main.local", "mkdir Desktop/test")).!
Process(Seq("ssh", "user#Main.local", "mkdir", "Desktop/test")).!
Using the form of Process.apply that takes a Seq removes one level of ambiguity about where the boundaries between the arguments lie. But note that once the command reaches the remote host, it will be processed by the remote shell which will make its own decision about where to put the argument breaks. So for example if you wanted to make a directory with a space in the name, this works locally:
Process(Seq("mkdir", "foo bar")).!
but if you try the same thing remotely:
Process(Seq("ssh", "user#Main.local", "mkdir", "foo bar")).!
You'll get two directories named foo and bar, since the remote shell inserts an argument break.

How to use sudo inside of a Run Script build phase in Xcode 4?

I need use execute a command inside of a script in a Run Script build phase in Xcode 4 using sudo. However, the compiler complains:
sudo: no tty present and no askpass program specified
Anyone have a clever solution for this problem?
One solution is to place the sudo password in an executable shell script like the following:
#!/bin/bash
echo thesudopassword
This shell script might be called password.sh
Then, setup the environment variable SUDO_ASKPASS=password.sh
Once this is setup, the -A option can be passed to sudo. This option uses the ASKPASS program to obtain the sudo password. The ASKPASS program need only write the password to stdout.
So, for example,
sudo -A ditto -V /tmp/testserver.dst /
This is obviously a rather insecure solution, but it does work.
Two ideas that haven't been suggested yet, both of which are probably better/safer than the currently accepted answer:
First option would be to put the part of the script that needs to be run as root in a script file (.sh or something), and then make it setuid as root: chmod go-w,+sx scriptfile, sudo chown root scriptfile. This means that script will automatically run as root, which avoids you needing to authenticate to run it (just to change it). As long as its operation isn't subject to user input, this should be quite safe. (Of course, if you make a script that takes an input argument and deletes it or runs it, or does most anything else with it, that would not be safe.)
Second option would be to use applescript (possibly via osascript). Applescript allows you to do shell script "sudo command goes here" with administrator privileges, which will pop up a graphical dialog asking for a password.
The first of these options would be good for an automated environment, though it might not deal well with (for example) being checked into an SCM, or being sent to another user. The second option would work better with that, but requires a password input every time, so doesn't work as well for an automated build script.
Another solution to this problem is to modify sudoers file and add your account to it and state that you should never be asked for the sudo password. To accomplish this is fairly straightforward:
run:
sudo visudo
In the User privilege specification section add a line that looks like
youraccountname ALL=(ALL) NOPASSWD: ALL
Of course, this can be a dangerous thing to do, so be careful. I would suggest reading the man page for sudoers and visudo before going this route.
After much searching I found the following solution.
https://forum.juce.com/t/build-script-for-automatically-moving-built-aus-into-components-folder-xcode/13112
Summary
Create a keychain and store your admin password in the keychain
Create a script which uses /usr/bin/security to access the password In your run script,
Set the ASK_PASS env variable and use the -A option with sudo
You can either run commands directly as a administrator with the following (changing echo YourCommandHere > /tmp/hello to your command):
osascript -e 'do shell script "sudo echo YourCommandHere > /tmp/hello " with administrator privileges'
Or run a script in your source directory using:
osascript -e 'do shell script "bash -x $SOURCE_ROOT/MyAdminScript.sh 1>/tmp/build-log 2>/tmp/build-log.err" with administrator privileges'
This runs the script and logs it output to /tmp/build-log and /tmp/build-log.err
For useful variables in the script see https://help.apple.com/xcode/mac/8.0/#/itcaec37c2a6
You can also execute XCode giving it the project as parameter from the Terminal using sudo like this:
sudo /Developer/Applications/Xcode.app/Contents/MacOS/Xcode /path/to/your/project.xcodeproj
This is the easiest solution I could think of, but there may be some drawbacks, since you would be executing XCode as root.
No need to write your sudo password anywhere. Just open a terminal window and type
$ sudo echo "hello"
Once you've typed your password, it will be good for a while - not sure how long - and the shell spawned by Xcode will inherit this permission.
If you get the "no tty present" message again later, just repeat the procedure

Bash script: Turn on errors?

After designing a simple shell/bash based backup script on my Ubuntu engine and making it work, I've uploaded it to my Debian server, which outputs a number of errors while executing it.
What can I do to turn on "error handling" in my Ubuntu machine to make it easier to debug?
ssh into the server
run the script by hand with either -v or -x or both
try to duplicate the user, group, and environment of the error run in your terminal window If necessary, run the program with something like "su -c 'sh -v script' otheruser
You might also want to pipe the result of the bad command, particularly if run by cron(8), into /bin/logger, perhaps something like:
sh -v -x badscript 2>&1 | /bin/logger -t badscript
and then go look at /var/log/messages.
Bash lets you turn on debugging selectively, or completely with the set command. Here is a good reference on how to debug bash scripts.
The command set -x will turn on debugging anywhere in your script. Likewise, set +x will turn it off again. This is useful if you only want to see debug output from parts of your script.
Change your shebang line to include the trace option:
#!/bin/bash -x
You can also have Bash scan the file for errors without running it:
$ bash -n scriptname

Resources