setsid: can't execute './test.sh': Exec format error - bash

I tried to execute setsid ./test.sh command on Alpine OS in a docker container.
And it says 'Exec format error'. then I added a header bang '
#!/usr/bin/env bash' to that script. It works.
But the same command and script without header on centos6 works well.
I've digged into it deeply. Seems that setsid is a system call which use execvp to execute command, execvp will treat the script as an execute file.
My script.sh has execute permission and can run with './script.sh'. Why does the script behave differently on alpine and centos?

Related

Running into error with BASH script with permission denied, but when running the command directly in bash shell its getting executed

When running below command directly in bash shell, I am able to get the output. But when I am passing it via BASH script getting access denied. Any help would be appreciated
$ jq -r '.id' Repooutput.txt
dad04f6d-4e06-4420-b0bc-cb2dcfee2dcf
Error:
$ sh test.sh
test.sh: line 3: /c/ProgramData/chocolatey/bin/jq: Permission denied
I think the reason is that when executing the script with sh test.sh we're asking the POSIX interpreter (shell) to execute the content on the script, while when executing it with ./test.sh we're asking the script to "execute itself".
For the latter, the file needs to have execution permissions, which you can add with
chmod +x test.sh
Issue was with the naming convention of JQ inside BASH folder path, because of which the script was unable to pick the command. Renaming the JQ within BASH folder resolved this

Launch bash subshell and run commands in a script

I want to write a shell script that does the following:
Activate pipenv virtual environment
Runs mkdocs serve which starts a local dev server for my mkdocs documentation
If I do the naïve thing and put this in my script:
cd <my-docs-directory>
pipenv shell
mkdocs serve
it fails because pipenv shell "launches a subshell in the virtual environment". I need to pass the mkdocs serve command into the virtual shell (and preferably land in that same shell after running the script ).
Thanks in advance!
Answer
Philippe's answer works. Here's why.
pipenv run bash -c 'mkdocs serve ; exec bash --norc'
Pipenv allows you to run a command in the virtual environment without launching a shell:
$ pipenv run <insert command here>
bash -c <insert command here> allows you to pass a command to bash to execute
$ bash -c "echo hello"
hello
exec serves to replace current shell process with a command, so that parent goes a way and child owns pid. Here's a related question on AskUbuntu.
You can use this command :
pipenv run bash -c 'mkdocs serve ; exec bash --norc'

How to run a sh script with CLI container using the docker exec command? [duplicate]

This question already has answers here:
Pass commands as input to another command (su, ssh, sh, etc)
(3 answers)
Closed 3 years ago.
I want to create s sh script but it stops when "docker exec -it cli bash" is executed and do not go to the next line. How to run the other commands on root?
root#ee3abae377df:/opt/gopath/src/github.com/hyperledger/fabric/peer#
Stops here and i am not able do execute the next command
docker exec -it cli bash
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin#org1.example.com/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CHANNEL_NAME=mychannel
docker exec -it creates an interactive docker container. It starts a new shell in your current terminal. This blocks the rest of the commands from running until you kill or exit the container. The rest of the commands you have will in fact be run, once you exit the container.
I assume this is not desired. You should look into creating an entrypoint in a custom Dockerfile for your docker container where you execute the remainder of the commands in your script.
If you haven't created a Dockerfile before, the getting started guide from Docker is a pretty good intro to everything docker-related.
Executing commands using CLI on any peer
As per the description you have given, cli is pointing to
peer0.org1.example.com:7051. (Please check your docker-compose file
and there would be one service with container name as "cli" and image
as hyperledger/fabric-tools)
When you are executing "docker exec -it cli bash", you are entering
into container of peer0.org1. It provides an interactive shell to
you.
Let us consider we want to install chaincode using cli on Pee1 Org1, create one test.sh file and write the following cammand inside test.sh file
docker exec -e "CORE_PEER_LOCALMSPID=Org1MSP" -e "CORE_PEER_ADDRESS=peer1.org1.example.com:7051" -e "CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin#org1.example.com/msp" cli peer chaincode install -n cc_name -v cc_version -p cc_path
Here we are passing environment varibles CORE_PEER_ADDRESS and CORE_PEER_MSPCONFIGPATH.
Then just execute test.sh file, the chaincode will be installed on peer1 provided container is already running and environment varibles are correct. (please provide correct chaincode path, name, and version)
You should leverage the option given by #jeremysprofile. But still, if you want to achieve it through shell script then you might want to write a expect script along with shell script or might merge both the scripts in one. It should look something like this :
#!/usr/bin/expect -f
expect "*root*" {
send -- "<your command>\r"
send -- "exit \r"
}
Expect is a program that "talks" to other interactive programs according to a script. Following the script, Expect knows what can be expected from a program and what the correct response should be.
Here is the Linux man Page.

Why this command "google-auth" works in the terminal but not from bash script?

I have installed libpam-google-authenticator and freeradius on server ubuntu 16.0405. Everything works good, except for if I use the command google-auth in bash script I get a error message "google-auth: command not found"
But the same works if I put it on terminal directly.
#!/bin/bash
google-auth
That is not a bash script.
To make it a bash script, your first line needs to include a "#" as follows:
#!/bin/bash
google-auth
Also, you need to ensure that the script is executable:
chmod +x yourscript.sh
Hopefully that will solve your problem.
As per the comments below, it seems like the command "google-auth" was an alias which wasn't being established in the child shell.

How to force ssh to execute bash instead of the user default on the remote machine?

I want to execute a bash script with ssh but when I try this it's using ksh which is the user's default shell.
I can't change that default.
So, how can I trick ssh to execute my script with bash instead of the default shell?
Make this the first line of your script:
#!/usr/bin/env bash
Edit: As per this, the utility of /usr/bin/env is dubious. So, you probably want:
#!/bin/bash
Replace /bin/bash with the actual path of bash executable.
You can call your script explicitly with bash:
ssh <ssh-opts> bash <scriptname>
This way there will be a ksh executed at login, but inside ksh you start a bash executing your script.

Resources