Expected: ',', received: ']' AWS SSM RunShellScript - bash

I want to update many instances, so I have made a script with this command:
aws ssm send-command --instance-ids "$y" --document-name AWS-RunShellScript --parameters commands='yum -y update; needs-restarting -r; if \[ $? -eq 1 \]; then exit 194' --cloud-watch-output-config "CloudWatchOutputEnabled=true"
Instead of running the command on the machines specified by $y, it says:
Error parsing parameter '--parameters': Expected: ',', received: ']' for input: commands=yum -y update; needs-restarting -r; if \[ 252 -eq 1 \]; then exit 194; else exit 0; fi
Note that the $? is referenced as 252 for some reason.

Try putting double quotes around the value for --parameters:
aws ssm send-command --instance-ids "$y" --document-name AWS-RunShellScript --parameters "commands='yum -y update; needs-restarting -r; if \[ $? -eq 1 \]; then exit 194'" --cloud-watch-output-config "CloudWatchOutputEnabled=true"
See the examples in the aws-cli reference.

Related

Issue with Bash script, i am new to bash, unable to understand the syntax error

I am new to bash scripting, I am writing a script that will deploy a new artifact to AWS Elasticbeanstalk, rather than going to AWS UI, and developers taking a long time. please see below and let me know if I am doing anything wrong. I am worried about this part:
if [ "$1" = "help" ] HELP <<EOF
then
read -r -d ''
Usage:
\t$(basename $0) list - list all applications
\t$(basename $0) deploy - deploy artifact to an environment
EOF
die "$HELP"
exit 0
fi
Running this command to run the script:
AWS_PROFILE=default ARTIFACT_BUCKET=myawsstudybucket ARTIFACT_NAME=artifact1.zip ./deploy.sh deploy demo-app Demoapp-env artifact.zip
#!/bin/bash
PROFILE=$(aws sts get-caller-identity --query Account)
RED='\033[0;31m'
COLOR_OFF='\033[0m'
if [ -z "$PROFILE" ]
then
echo "Credentials missing"
else
region=$(aws configure get region)
fi
if [ "$1" = "list" ]
then
echo $(aws elasticbeanstalk describe-applications --query "Applications[].ApplicationName")
exit 0
fi
if [ "$1" = "help" ] HELP <<EOF
then
read -r -d ''
Usage:
\t$(basename $0) list - list all applications
\t$(basename $0) deploy <app-name> <environment-name> <local-artifact-path> - deploy artifact to an environment
EOF
die "$HELP"
exit 0
fi
die() { echo -e "$*" >&2; exit 1; }
[[ -z $EB_APP ]] && die "ERROR: Missing application name"
[[ -z $EB_ENV ]] && die "ERROR: Missing application environment"
[[ -z $EB_ARTIFACT ]] && die "ERROR: Missing application artifact location"
s3path="s3://$ARTIFACT_LOCATION/$ARTIFACT_NAME"
aws s3 cp $artifactpath $s3path
versionlabel=$(date +%s%N)
aws elasticbeanstalk create-application-version --application-name "$ebapp" --version-label $versionlabel --source-bundle S3Bucket=$ARTIFACT_LOCATION,S3Key=$ARTIFACT_NAME
aws elasticbeanstalk update-environment --environment-name $ebenv --version-label $versionlabel
echo "Deployment in progress"
while [[ "$STATUS" != OK ]] && [[ "$STATUS" != Severe ]];
do
echo "Checking environment status"
status=$(aws elasticbeanstalk describe-environment-health --environment-name $ebenv --attribute-names HealthStatus --query "HealthStatus"| tr -d '"')
echo "Current status: $status."
sleep 5
done
echo "Deployed successfully"
That part is definitely strange. What should the word HELP do after the ]?
You probably wanted something like
if [ "$1" = "help" ]
then
echo Press Enter to display the help...
read
cat <<-EOF
Usage:
$(basename $0) list - list all applications
$(basename $0) deploy <app-name> <environment-name> <local-artifact-path> - deploy artifact to an environment
EOF
fi
Note that you need the real Tab before the closing EOF.
Or maybe you wanted this?
die() { echo -e "$*" >&2; exit 1; }
if [ "$1" = "help" ]
then
HELP="
Usage:
$(basename $0) list - list all applications
$(basename $0) deploy <app-name> <environment-name> <local-artifact-path> - deploy artifact to an environment
"
die "$HELP"
fi
Strings in quotes can be multiline.
Note that die must be declared before you can call it.

How can I use Expect to automate an AWS job? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last year.
Improve this question
I have a very large copy to my local machine from an S3 bucket, which iterates through a file of identifiers and copies matching files. It all works well… except that the copy is so large that it keeps timing out and asking me for my password (every 2 - 3 hours). All told, it took a fortnight to run last time I ran it - but would have been much faster if I'd entered the password immediately that I was requested for it (which was never going to happen because of meals / sleep / other).
There are two scripts. One does the actual work (the core script) and one does the reading of the file of identifiers and calls the core script.
I'd like to automate this task, but I'm having trouble working out how to exactly.
This is the core of the working (but slow, because it asks for the password) script…
#!/bin/bash
function errorexit() {
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
exit 1
}
​
FILEID=$(echo $1)
​
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
​
aws-adfs login --profile=default --adfs-host=myhost.com --role-arn=myroledeets --region=eu-west-1 && export AWS_PROFILE=default
if [ $? -ne 0 ]; then
exit 1
fi
​
ASSUMED_ROLE=$(aws sts assume-role --role-arn myroledeets --role-session-name seshname)
export AWS_SECRET_ACCESS_KEY=$(echo $ASSUMED_ROLE | jq -r .Credentials.SecretAccessKey)
export AWS_ACCESS_KEY_ID=$(echo $ASSUMED_ROLE | jq -r .Credentials.AccessKeyId)
export AWS_SESSION_TOKEN=$(echo $ASSUMED_ROLE | jq -r .Credentials.SessionToken)
​
if [ ${#AWS_ACCESS_KEY_ID} -lt 16 ] || [ ${#AWS_ACCESS_KEY_ID} -gt 128 ]; then
echo "Access Key Failure" >&2
errorexit
fi
​
if [ ${#AWS_SECRET_ACCESS_KEY} -lt 16 ] || [ ${#AWS_SECRET_ACCESS_KEY} -gt 128 ]; then
echo "Secret Access Key Failure" >&2
errorexit
fi
​
if [ ${#AWS_SESSION_TOKEN} -lt 128 ]; then
echo "Session Token Failure" >&2
errorexit
fi
​
AWSPATH="s3://mypath/$FILEID"
aws s3 ls $AWSPATH | cut -c 32- | while IFS= read -r line; do
COPYPATH="s3://mypath/$FILEID/$line"
echo $COPYPATH
aws s3 cp $COPYPATH ./$FILEID/$line --recursive
done
if [ $? -ne 0 ]; then
errorexit
fi
​
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
​
exit 0
I thought it would be a good idea to use Expect to sort this issue. So I did the following (this doesn't work!):
#!/bin/bash
function errorexit() {
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
exit 1
}
​
ACCESSPW=$(echo $1)
FILEID=$(echo $2)
​
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
​
expect <<EOD
spawn aws-adfs login --profile=default --adfs-host=myhost.com --role-arn=myroledeets --region=eu-west-1
set timeout 5
expect -r {
"Password: $" {
send "$ACCESSPW\r"
}
}
EOD
​
if [ $? -ne 0 ]; then
exit 1
fi
​
export AWS_PROFILE=default
ASSUMED_ROLE=$(aws sts assume-role --role-arn myroledeets --role-session-name seshname)
export AWS_SECRET_ACCESS_KEY=$(echo $ASSUMED_ROLE | jq -r .Credentials.SecretAccessKey)
export AWS_ACCESS_KEY_ID=$(echo $ASSUMED_ROLE | jq -r .Credentials.AccessKeyId)
export AWS_SESSION_TOKEN=$(echo $ASSUMED_ROLE | jq -r .Credentials.SessionToken)
​
if [ ${#AWS_ACCESS_KEY_ID} -lt 16 ] || [ ${#AWS_ACCESS_KEY_ID} -gt 128 ]; then
echo "Access Key Failure" >&2
errorexit
fi
​
if [ ${#AWS_SECRET_ACCESS_KEY} -lt 16 ] || [ ${#AWS_SECRET_ACCESS_KEY} -gt 128 ]; then
echo "Secret Access Key Failure" >&2
errorexit
fi
​
if [ ${#AWS_SESSION_TOKEN} -lt 128 ]; then
echo "Session Token Failure" >&2
errorexit
fi
​
AWSPATH="s3://mypath/$FILEID"
aws s3 ls $AWSPATH | cut -c 32- | while IFS= read -r line; do
COPYPATH="s3://mypath/$FILEID/$line"
echo $COPYPATH
aws s3 cp $COPYPATH ./$FILEID/$line --recursive
done
if [ $? -ne 0 ]; then
errorexit
fi
​
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
​
exit 0
So what happens? Well, when I try to run this Expect automated version I get…
./awscopy.sh <password> <file>
spawn aws-adfs login --profile=default --adfs-host=myhost.com --role-arn=myroledeets --region=eu-west-1
2022-02-14 11:09:29,372 [authenticator authenticator.py:authenticate] [43954-MainProcess] [6536770074-MainThread] - ERROR: Cannot extract saml assertion. Re-authentication needed?
Password:
An error occurred (ExpiredToken) when calling the AssumeRole operation: The security token included in the request is expired
Access Key Failure
As you may have guessed, this is the first time I've tried to use Expect. What have I done wrong?

How to wait in bash script until AWS instance creation is complete

I'm using a bash script to create an AWS instance via CLI and a cloudformation template. I want my script to wait until the instance creation is complete before I move on in my script. Right now, I'm using a while loop to "describe-stacks" every 5 seconds, and breaking out of the loop when the status = "CREATE_COMPLETE" or some failure status. Does anyone know of a more elegant way to do this?
stackStatus="CREATE_IN_PROGRESS"
while [[ 1 ]]; do
echo "${AWS_CLI_PATH}" cloudformation describe-stacks --region "${CfnStackRegion}" --stack-name "${CfnStackName}"
response=$("${AWS_CLI_PATH}" cloudformation describe-stacks --region "${CfnStackRegion}" --stack-name "${CfnStackName}" 2>&1)
responseOrig="$response"
response=$(echo "$response" | tr '\n' ' ' | tr -s " " | sed -e 's/^ *//' -e 's/ *$//')
if [[ "$response" != *"StackStatus"* ]]
then
echo "Error occurred creating AWS CloudFormation stack. Error:"
echo " $responseOrig"
exit -1
fi
stackStatus=$(echo $response | sed -e 's/^.*"StackStatus"[ ]*:[ ]*"//' -e 's/".*//')
echo " StackStatus: $stackStatus"
if [[ "$stackStatus" == "ROLLBACK_IN_PROGRESS" ]] || [[ "$stackStatus" == "ROLLBACK_COMPLETE" ]] || [[ "$stackStatus" == "DELETE_IN_PROGRESS" ]] || [[ "$stackStatus" == "DELETE_COMPLETE" ]]; then
echo "Error occurred creating AWS CloudFormation stack and returned status code ROLLBACK_IN_PROGRESS. Details:"
echo "$responseOrig"
exit -1
elif [[ "$stackStatus" == "CREATE_COMPLETE" ]]; then
break
fi
# Sleep for 5 seconds, if stack creation in progress
sleep 5
done
The aws cli provides a wait subcommand for most of the commands that create resources. For your scenario, you can use the wait subcommand to wait for the stack-create-complete event:
aws cloudformation wait stack-create-complete --stack-name myStackName
That is how I did it. After start of instance I wait for public IP:
INSTANCE_ID="$(aws ec2 run-instances --cli-input-json "${LAUNCH_SPEC}" | jq -r '.Instances[0].InstanceId')"
echo "Instance id ${INSTANCE_ID}"
while true; do
PUBLIC_IP="$(aws ec2 describe-instances --instance-ids ${INSTANCE_ID} | jq -r '.Reservations[0].Instances[0].PublicIpAddress')"
if [[ "${PUBLIC_IP}" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then break; fi
sleep 1
echo -n '.'
done
LAUNCH_SPEC defined previously
Ec2-wait-instance-exists seems like what you need:
http://docs.aws.amazon.com/cli/latest/reference/ec2/wait/instance-exists.html
The below is a general "check_status" function. Useful for multiple action such as checking whether stack has been deployed or an EKS cluster is up and whether nodes were added to it.
check_status() {
max_tries="$1"
test_command="$2"
required_value="$3"
error="$4"
ok="false"
for i in `seq 1 $max_tries`; do
return_value=$(eval ${test_command})
if [ "$return_value" == "$required_value" ]; then
ok="true"
break
else
echo -n "."
fi
sleep 5
done
if [ "$ok" == "false" ]; then
printf "\n\e[31mERROR:\e[0m $error\n"
exit 1
fi
}
check_vpc() {
echo "Waiting for stack status..."
vpc_stack_status="aws cloudformation describe-stacks --stack-
name=${vpc_stack_name} --query 'Stacks[0].StackStatus' --output text"
msg="Stack creation failed - giving up"
check_status "100" "$vpc_stack_status" "CREATE_COMPLETE" "$msg"
[[ $? == "0" ]] && echo "VPC stack deployed successfully"
}

Cannot install NPM using curl

Receiving this error when attempting to install NPM. Any help on this error is greatly appreciated.
$ curl http://npmjs.org/install.sh | sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 85 0 85 0 0 2226 0 --:--:-- --:--:-- --:--:-- 4473
sh: line 1: syntax error near unexpected token `newline'
sh: line 1: `<html>Moved: https://npmjs.org/install.sh'
Changed the command from http://... --> https:// and still no luck.
Other info:
OS: Mac OSX 10.8.2
CURL: curl 7.24.0 (x86_64-apple-darwin12.0)
So I attempted the install as a superuser and was promptly met with this mountain of text. I'm completely lost here.
$ sudo curl https://npmjs.org/install.sh | sh
Password:
#!/bin/sh
# A word about this shell script:
#
# It must work everywhere, including on systems that lack
# a /bin/bash, map 'sh' to ksh, ksh97, bash, ash, or zsh,
# and potentially have either a posix shell or bourne
# shell living at /bin/sh.
#
# See this helpful document on writing portable shell scripts:
# http://www.gnu.org/s/hello/manual/autoconf/Portable-Shell.html
#
# The only shell it won't ever work on is cmd.exe.
if [ "x$0" = "xsh" ]; then
# run as curl | sh
# on some systems, you can just do cat>npm-install.sh
# which is a bit cuter. But on others, &1 is already closed,
# so catting to another script file won't do anything.
curl -s https://npmjs.org/install.sh > npm-install-$$.sh
sh npm-install-$$.sh
ret=$?
rm npm-install-$$.sh
exit $ret
fi
# See what "npm_config_*" things there are in the env,
# and make them permanent.
# If this fails, it's not such a big deal.
configures="`env | grep 'npm_config_' | sed -e 's|^npm_config_||g'`"
npm_config_loglevel="error"
if [ "x$npm_debug" = "x" ]; then
(exit 0)
else
echo "Running in debug mode."
echo "Note that this requires bash or zsh."
set -o xtrace
set -o pipefail
npm_config_loglevel="verbose"
fi
export npm_config_loglevel
# make sure that node exists
node=`which node 2>&1`
ret=$?
if [ $ret -eq 0 ] && [ -x "$node" ]; then
(exit 0)
else
echo "npm cannot be installed without nodejs." >&2
echo "Install node first, and then try again." >&2
echo "" >&2
echo "Maybe node is installed, but not in the PATH?" >&2
echo "Note that running as sudo can change envs." >&2
echo ""
echo "PATH=$PATH" >&2
exit $ret
fi
# set the temp dir
TMP="${TMPDIR}"
if [ "x$TMP" = "x" ]; then
TMP="/tmp"
fi
TMP="${TMP}/npm.$$"
rm -rf "$TMP" || true
mkdir "$TMP"
if [ $? -ne 0 ]; then
echo "failed to mkdir $TMP" >&2
exit 1
fi
BACK="$PWD"
ret=0
tar="${TAR}"
if [ -z "$tar" ]; then
tar="${npm_config_tar}"
fi
if [ -z "$tar" ]; then
tar=`which tar 2>&1`
ret=$?
fi
if [ $ret -eq 0 ] && [ -x "$tar" ]; then
echo "tar=$tar"
echo "version:"
$tar --version
ret=$?
fi
if [ $ret -eq 0 ]; then
(exit 0)
else
echo "No suitable tar program found."
exit 1
fi
# Try to find a suitable make
# If the MAKE environment var is set, use that.
# otherwise, try to find gmake, and then make.
# If no make is found, then just execute the necessary commands.
# XXX For some reason, make is building all the docs every time. This
# is an annoying source of bugs. Figure out why this happens.
MAKE=NOMAKE
if [ "x$MAKE" = "x" ]; then
make=`which gmake 2>&1`
if [ $? -eq 0 ] && [ -x $make ]; then
(exit 0)
else
make=`which make 2>&1`
if [ $? -eq 0 ] && [ -x $make ]; then
(exit 0)
else
make=NOMAKE
fi
fi
else
make="$MAKE"
fi
if [ -x "$make" ]; then
(exit 0)
else
# echo "Installing without make. This may fail." >&2
make=NOMAKE
fi
# If there's no bash, then don't even try to clean
if [ -x "/bin/bash" ]; then
(exit 0)
else
clean="no"
fi
node_version=`"$node" --version 2>&1`
ret=$?
if [ $ret -ne 0 ]; then
echo "You need node to run this program." >&2
echo "node --version reports: $node_version" >&2
echo "with exit code = $ret" >&2
echo "Please install node before continuing." >&2
exit $ret
fi
t="${npm_install}"
if [ -z "$t" ]; then
# switch based on node version.
# note that we can only use strict sh-compatible patterns here.
case $node_version in
0.[0123].* | v0.[0123].*)
echo "You are using an outdated and unsupported version of" >&2
echo "node ($node_version). Please update node and try again." >&2
exit 99
;;
v0.[45].* | 0.[45].*)
echo "install npm#1.0"
t=1.0
;;
v0.[678].* | 0.[678].*)
echo "install npm#1.1"
t=1.1
;;
*)
echo "install npm#latest"
t="latest"
;;
esac
fi
# the npmca cert
cacert='
-----BEGIN CERTIFICATE-----
MIIChzCCAfACCQDauvz/KHp8ejANBgkqhkiG9w0BAQUFADCBhzELMAkGA1UEBhMC
VVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMQwwCgYDVQQKEwNucG0x
IjAgBgNVBAsTGW5wbSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxDjAMBgNVBAMTBW5w
bUNBMRcwFQYJKoZIhvcNAQkBFghpQGl6cy5tZTAeFw0xMTA5MDUwMTQ3MTdaFw0y
MTA5MDIwMTQ3MTdaMIGHMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNV
BAcTB09ha2xhbmQxDDAKBgNVBAoTA25wbTEiMCAGA1UECxMZbnBtIENlcnRpZmlj
YXRlIEF1dGhvcml0eTEOMAwGA1UEAxMFbnBtQ0ExFzAVBgkqhkiG9w0BCQEWCGlA
aXpzLm1lMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLI4tIqPpRW+ACw9GE
OgBlJZwK5f8nnKCLK629Pv5yJpQKs3DENExAyOgDcyaF0HD0zk8zTp+ZsLaNdKOz
Gn2U181KGprGKAXP6DU6ByOJDWmTlY6+Ad1laYT0m64fERSpHw/hjD3D+iX4aMOl
y0HdbT5m1ZGh6SJz3ZqxavhHLQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAC4ySDbC
l7W1WpLmtLGEQ/yuMLUf6Jy/vr+CRp4h+UzL+IQpCv8FfxsYE7dhf/bmWTEupBkv
yNL18lipt2jSvR3v6oAHAReotvdjqhxddpe5Holns6EQd1/xEZ7sB1YhQKJtvUrl
ZNufy1Jf1r0ldEGeA+0ISck7s+xSh9rQD2Op
-----END CERTIFICATE-----
'
echo "$cacert" > "$TMP/cafile.crt"
cacert="$TMP/cafile.crt"
# need to echo "" after, because Posix sed doesn't treat EOF
# as an implied end of line.
url=`(curl -SsL --cacert "$cacert" https://registry.npmjs.org/npm/$t; echo "") \
| sed -e 's/^.*tarball":"//' \
| sed -e 's/".*$//'`
ret=$?
if [ "x$url" = "x" ]; then
ret=125
# try without the -e arg to sed.
url=`(curl -SsL --cacert "$cacert" https://registry.npmjs.org/npm/$t; echo "") \
| sed 's/^.*tarball":"//' \
| sed 's/".*$//'`
ret=$?
if [ "x$url" = "x" ]; then
ret=125
fi
fi
if [ $ret -ne 0 ]; then
echo "Failed to get tarball url for npm/$t" >&2
exit $ret
fi
echo "fetching: $url" >&2
cd "$TMP" \
&& curl -SsL --cacert "$cacert" "$url" \
| $tar -xzf - \
&& rm "$cacert" \
&& cd "$TMP"/* \
&& (req=`"$node" bin/read-package-json.js package.json engines.node`
if [ -d node_modules ]; then
"$node" node_modules/semver/bin/semver -v "$node_version" -r "$req"
ret=$?
else
"$node" bin/semver.js -v "$node_version" -r "$req"
ret=$?
fi
if [ $ret -ne 0 ]; then
echo "You need node $req to run this program." >&2
echo "node --version reports: $node_version" >&2
echo "Please upgrade node before continuing." >&2
exit $ret
fi) \
&& (ver=`"$node" bin/read-package-json.js package.json version`
isnpm10=0
if [ $ret -eq 0 ]; then
req=`"$node" bin/read-package-json.js package.json engines.node`
if [ -d node_modules ]; then
if "$node" node_modules/semver/bin/semver -v "$ver" -r "1"
then
isnpm10=1
fi
else
if "$node" bin/semver -v "$ver" -r ">=1.0"; then
isnpm10=1
fi
fi
fi
ret=0
if [ $isnpm10 -eq 1 ] && [ -f "scripts/clean-old.sh" ]; then
if [ "x$skipclean" = "x" ]; then
(exit 0)
else
clean=no
fi
if [ "x$clean" = "xno" ] \
|| [ "x$clean" = "xn" ]; then
echo "Skipping 0.x cruft clean" >&2
ret=0
elif [ "x$clean" = "xy" ] || [ "x$clean" = "xyes" ]; then
NODE="$node" /bin/bash "scripts/clean-old.sh" "-y"
ret=$?
else
NODE="$node" /bin/bash "scripts/clean-old.sh" </dev/tty
ret=$?
fi
fi
if [ $ret -ne 0 ]; then
echo "Aborted 0.x cleanup. Exiting." >&2
exit $ret
fi) \
&& (if [ "x$configures" = "x" ]; then
(exit 0)
else
echo "./configure "$configures
echo "$configures" > npmrc
fi) \
&& (if [ "$make" = "NOMAKE" ]; then
(exit 0)
elif "$make" uninstall install; then
(exit 0)
else
make="NOMAKE"
fi
if [ "$make" = "NOMAKE" ]; then
"$node" cli.js rm npm -gf
"$node" cli.js install -gf
fi) \
&& cd "$BACK" \
&& rm -rf "$TMP" \
&& echo "It worked"
ret=$?
if [ $ret -ne 0 ]; then
echo "It failed" >&2
fi
exit $ret
You are getting the install.sh script, you just have to execute it. Do this
curl -O https://npmjs.org/install.sh
sudo sh install.sh
Update
If you get a 301 Moved Permanently file instead, try adding -L option to follow the redirect like this:
curl -O -L https://npmjs.org/install.sh
The original command would work if you use the current location (and not the old one) (at least on my system, same settings).
Meaning, use:
curl https://npmjs.org/install.sh | sh
instead of:
curl http://npmjs.org/install.sh | sh
I have tried many times with various curl options. But the main problem is npm site's https certificate verification. Finally this has worked for me:
curl -k -O -L https://npmjs.org/install.sh
Hope it will help somebody else.
This is still broken somehow? Trying following:
$curl https://npmjs.org/install.sh | sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 93 0 93 0 0 78 0 --:--:-- 0:00:01 --:--:-- 79
sh: line 1: syntax error near unexpected token `newline'
sh: line 1: `<html>Moved: https://www.npmjs.org/install.sh'
and with (https) www.npmjs.org :
$curl https://www.npmjs.org/install.sh | sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 6707 100 6707 0 0 6446 0 0:00:01 0:00:01 --:--:-- 6442
npm-install-606.sh: line 1: syntax error near unexpected token `newline'
npm-install-606.sh: line 1: `<html>Moved: https://www.npmjs.org/install.sh'
Using OS X Maverics 10.9.1
$uname -a
Darwin Esan-iMac.local 13.0.0 Darwin Kernel Version 13.0.0: Thu Sep 19 22:22:27 PDT 2013; root:xnu-2422.1.72~6/RELEASE_X86_64 x86_64
$curl --version
curl 7.30.0 (x86_64-apple-darwin13.0) libcurl/7.30.0 SecureTransport zlib/1.2.5
Should it work with similar env; someone tested???
Am I missing something. Remembering that it is discouraged to run with sudo?
Not yet tried separate download and 'sh'-command.
Edit: yes, separate download curl -O https://www.npmjs.org/install.sh and sh install.sh works fine, after changing owner for /usr/local/lib/node_modules/npm because previously installed with sudo. But it has nothing to do with error message, or can it?
Adding -L helped me. For example:
curl -L http://www.npmjs.org/install.sh | sh
In addition to this url: https://stackoverflow.com/a/15508817/1979882
In my case, for Debian OS it is important to create a symbol link:
ln -s /usr/bin/nodejs /usr/bin/node
More detailed installation workflow is here.
If you have already install nvm, all you have to do is run nvm install version
For example if you are willing to install version 8.0.0, then you run
->$ nvm install 8.0.0
then
->$ nvm use 8.0.0
and you can run all your npm commands....

Bash remote files system directory test

the more I learn bash the more questions I have, and the more I understand why very few people do bash. Easy is something else, but I like it.
I have managed to figure out how to test directories and there writablity, but have a problem the minute I try to do this with a remote server over ssh. The first instance testing the /tmp directory works fine, but when the second part is called, I get line 0: [: missing]'`
Now if I replace the \" with a single quote, it works, but I thought that single quotes turn of variable referencing ?? Can someone explain this to me please ? Assuming that the tmp directory does exist and is writable, here the script so far
#!/bin/bash
SshHost="hostname"
SshRsa="~/.ssh/id_rsa"
SshUser="user"
SshPort="22"
Base="/tmp"
Sub="one space/another space"
BaseBashExist="bash -c \"[ -d \"$Base\" ] && echo 0 && exit 0 || echo 1 && exit 1\""
SSHBaseExist=$( ssh -l $SshUser -i $SshRsa -p $SshPort $SshHost ${BaseBashExist} )
echo -n $Base
if [ $? -eq 0 ]
then
echo -n "...OK..."
else
echo "...FAIL"
exit 1
fi
BaseBashPerm="bash -c \"[ -w \"$Base\" ] && echo 0 && exit 0 || echo 1 && exit 1\""
SSHBaseExist=$( ssh -l $SshUser -i $SshRsa -p $SshPort $SshHost ${BaseBashPerm} )
if [ $? -eq 0 ]
then
echo "...writeable"
else
echo "...not writeable"
fi
BaseAndSub="$Base/$Sub"
BaseAndSubBashExist="bash -c \"[ -d \"$BaseAndSub\" ] && echo 0 && exit 0 || echo 1 && exit 1\""
SSHBaseAndSubExist=$( ssh -l $SshUser -i $SshRsa -p $SshPort $SshHost ${BaseAndSubBashExist} )
echo -n $BaseAndSub
if [ $? -eq 0 ]
then
echo -n "...OK..."
else
echo "...FAIL"
exit 1
fi
BaseAndSubBashPerm="bash -c \"[ -w \"$BaseAndSub\" ] && echo 0 && exit 0 || echo 1 && exit 1\""
SSHBaseAndSubPerm=$( ssh -l $SshUser -i $SshRsa -p $SshPort $SshHost ${BaseAndSubBashPerm} )
if [ $? -eq 0 ]
then
echo -n "...writeable"
else
echo "...not writeable"
fi
exit 0
The first thing you should do is refactor your code with simplicity in mind, then the quoting error will go away as well. Try:
if ssh [flags] test -w "'$file'"; then
Encapsulate your SSH flags in a ssh config to facilitate re-use, and your script will shorten dramatically.
You are fine with single quotes in this context; by the time the script is seen by the remote bash, your local bash has already substituted in the variables you want to substitute.
However, your script is a total mess. You should put the repetitive code in functions if you cannot drastically simplify it.
#!/bin/bash
remote () {
# most of the parameters here are at their default values;
# why do you feel you need to specify them?
#ssh -l "user" -i ~/.ssh/id_rsa -p 22 hostname "$#"
ssh hostname "$#"
# —---------^
# if you really actually need to wrap the remote
# commands in bash -c "..." then add that here
}
exists_and_writable () {
echo -n "$1"
if remote test -d "$1"; then
echo -n "...OK..."
else
echo "...FAIL"
exit 1
fi
if remote test -w "$1"; then
echo "...writeable"
else
echo "...not writeable"
fi
}
Base="/tmp"
# Note the need for additional quoting here
Sub="one\\ space/another\\ space"
exists_and_writable "$Base"
BaseAndSub="$Base/$Sub"
exist_and_writable "$BaseAndSub"
exit 0
ssh -qnx "useraccount#hostname"
"test -f ${file absolute path} ||
echo ${file absolute path} no such file or directory"

Resources