##!/bin/bash
set -e
backup_dir='/home/my/backup'
user='my'
su $user <<EOFHD
cat << 'EOF' > $backup_dir/autorestartnftables.sh
#!/bin/bash
SERVICENAME="nftables"
# return value is 0 if running
STATUS=$?
if [[ "$STATUS" -ne "0" ]]; then
echo "Service '$SERVICENAME' is not curently running... Starting now..."
systemctl start $SERVICENAME
fi
EOF
chmod +x $backup_dir/autorestartnftables.sh
EOFHD
Above script is used to create autorestartnftables.sh,expect result as below:
#!/bin/bash
SERVICENAME="nftables"
# return value is 0 if running
STATUS=$?
if [[ "$STATUS" -ne "0" ]]; then
echo "Service '$SERVICENAME' is not curently running... Starting now..."
systemctl start $SERVICENAME
fi
autorestartnftables.sh after run sudo bash ./example.sh:
#!/bin/bash
SERVICENAME="nftables"
# return value is 0 if running
STATUS=0
if [[ "" -ne "0" ]]; then
echo "Service '' is not curently running... Starting now..."
systemctl start
fi
Where is the problem?
Do not nest, nest, nest. Instead use declare -f and functions to transfer work to unrelated context.
##!/bin/bash
set -e
backup_dir='/home/my/backup'
user='my'
work() {
cat << 'EOF' > $backup_dir/autorestartnftables.sh
#!/bin/bash
SERVICENAME="nftables"
# return value is 0 if running
STATUS=$?
if [[ "$STATUS" -ne "0" ]]; then
echo "Service '$SERVICENAME' is not curently running... Starting now..."
systemctl start $SERVICENAME
fi
EOF
chmod +x $backup_dir/autorestartnftables.sh
}
su "$user" bash -c "$(declare -p backup_dir); $(declare -f work); work"
In this case, you could check if the user running your script is the user you want and then restart your script with that user:
##!/bin/bash
set -e
backup_dir='/home/my/backup'
user='my'
if [[ "$USER" != "$user" ]]; then
# restart yourself as that user
exec sudo -u "$user" "$0" "$#"
fi
cat << 'EOF' > $backup_dir/autorestartnftables.sh
#!/bin/bash
SERVICENAME="nftables"
# return value is 0 if running
STATUS=$?
if [[ "$STATUS" -ne "0" ]]; then
echo "Service '$SERVICENAME' is not curently running... Starting now..."
systemctl start $SERVICENAME
fi
EOF
chmod +x $backup_dir/autorestartnftables.sh
Check your scripts with shellcheck.
I am trying to make a grep call in a command substitution in bash like so:
status=$(dpkg -s elasticsearch | grep "Status")
But when I run this in a script called elk.sh, I get the following output:
./elk.sh: 47: ./elk.sh: grep: not found
It seems that when I use command substitutions, grep is not found. But when I call it normaly in my script, it is working as usual.
Do you have any idea of what could be wrong?
EDIT: as my code is not sensitive, I am sharing it here, since it may help you to understand what is wrong.
Note that file elk.sh returns:
elk.sh: POSIX shell script, UTF-8 Unicode text executable
Here is the code:
#!/bin/sh
pInfo() {
if [ "$#" -ne 1 ]; then
echo "Invalid arguments: pInfo needs one string as argument."
exit 1
fi
echo "\033[32m[INFO]\033[0m $1"
}
pError() {
if [ "$#" -ne 1 ]; then
echo "Invalid arguments: pError needs one string as arguments."
exit 1
fi
echo "\033[31m[ERROR]\033[0m $1"
}
install_elk() {
wget "https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.4.2.deb" -q --show-progress
sudo dpkg -i "elasticsearch-6.4.2.deb"
sudo apt-get install -f
sudo rm -rRf "elasticsearch-6.4.2.deb"
}
which grep
echo $PATH
pInfo "Verifying ElasticSearch installation."
status=$(dpkg -s elasticsearch | grep Status)
if [ "$?" -ne 0 ] || [ -z "$status" ]; then
pError "ElasticSearch is not installed."
pInfo "Start the installation ? (y/n)"
read answer
if [ "$answer" != "y" ] && [ "$answer" != "n" ]; then
pError "Invalid answer. Just type 'y' (yes) or 'n' (no)."
exit 1
fi
if [ "$answer" = "y" ]; then
pInfo "Installing ElasticSearch..."
install_elk
else
pInfo "Not installing ElasticSearch."
exit 2
fi
fi
pInfo "ElasticSearch installed."
ps ax | grep -v grep | grep "elasticsearch" > /dev/null
if [ "$?" -eq 1 ]; then
pInfo "ElasticSearch not running. Starting..."
if [ ! -z "$(ps -p 1 | grep "systemd")" ]; then
pInfo "System running systemd."
sudo systemctl start elasticsearch.service
else
pInfo "System running init."
sudo -i service elasticsearch start
fi
fi
pInfo "ElasticSearch started."
exit 0
A call to elk.sh gives the following output:
$ ./elk.sh
/bin/grep
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
[INFO] Verifying ElasticSearch installation
[INFO] ElasticSearch installed
./elk.sh: 49: ./elk.sh: grep: not found
[INFO] ElasticSearch not running. Starting...
[INFO] System running systemd.
[INFO] ElasticSearch started.
EDIT: I found the issue: rewriting the line like so:
status=$(dpkg -s elasticsearch |grep "Status")
makes the commands works just fine. I just needed to remove the whitespace between the pipe and the grep command.
I might be blind, but I can't find the errors my script got, maybe you guys got better eyes than me :). I use a busybox compiled linux on a embedded system, Kernel 4.18.0. I found the base script here: Gist-Template
the following error is at "start":
./daemon: line 195: arithmetic syntax error
when I try "stop" these messages appear, but i dont see a unknown operand at line 0:
sh: 0: unknown operand
* Stopping Monitoring
my script:
#!/bin/sh
daemonName="Monitoring"
pidDir="."
pidFile="$pidDir/$daemonName.pid"
pidFile="$daemonName.pid"
logDir="."
# To use a dated log file.
# logFile="$logDir/$daemonName-"`date +"%Y-%m-%d"`".log"
# To use a regular log file.
logFile="$logDir/$daemonName.log"
# Log maxsize in KB
logMaxSize=1024 # 1mb
runInterval=300 # In seconds
doCommands() {
# This is where you put all the commands for the daemon.
echo "Running commands."
}
############################################################
# Below are the command functions
############################################################
hw_temp() {
cpu_temp=$(sensors|grep CPU|awk '{print $3}'|awk '{print ($0-int($0)<0.499)?int($0):int($0)+1}')
env_temp=$(sensors|grep ENV|awk '{print $3}'|awk '{print ($0-int($0)<0.499)?int($0):int($0)+1}')
pcb_temp=$(sensors|grep PCB|awk '{print $3}'|awk '{print ($0-int($0)<0.499)?int($0):int($0)+1}')
echo "$cpu_temp $env_temp $pcb_temp" >> /opt/monitoring/bla
}
############################################################
# Below is the skeleton functionality of the daemon.
############################################################
myPid=`echo $$`
setupDaemon() {
# Make sure that the directories work.
if [ ! -d "$pidDir" ]; then
mkdir "$pidDir"
fi
if [ ! -d "$logDir" ]; then
mkdir "$logDir"
fi
if [ ! -f "$logFile" ]; then
touch "$logFile"
else
# Check to see if we need to rotate the logs.
size=$((`ls -l "$logFile" | cut -d " " -f 8`/1024))
if [[ $size -gt $logMaxSize ]]; then
mv $logFile "$logFile.old"
touch "$logFile"
fi
fi
}
startDaemon() {
# Start the daemon.
setupDaemon # Make sure the directories are there.
if [[ `checkDaemon` = 1 ]]; then
echo " * \033[31;5;148mError\033[39m: $daemonName is already running."
exit 1
fi
echo " * Starting $daemonName with PID: $myPid."
echo "$myPid" > "$pidFile"
log '*** '`date +"%Y-%m-%d"`": Starting up $daemonName."
# Start the loop.
loop
}
stopDaemon() {
# Stop the daemon.
if [[ `checkDaemon` -eq 0 ]]; then
echo " * \033[31;5;148mError\033[39m: $daemonName is not running."
exit 1
fi
echo " * Stopping $daemonName"
log '*** '`date +"%Y-%m-%d"`": $daemonName stopped."
if [[ ! -z `cat $pidFile` ]]; then
kill -9 `cat "$pidFile"` &> /dev/null
fi
}
statusDaemon() {
# Query and return whether the daemon is running.
if [[ `checkDaemon` -eq 1 ]]; then
echo " * $daemonName is running."
else
echo " * $daemonName isn't running."
fi
exit 0
}
restartDaemon() {
# Restart the daemon.
if [[ `checkDaemon` = 0 ]]; then
# Can't restart it if it isn't running.
echo "$daemonName isn't running."
exit 1
fi
stopDaemon
startDaemon
}
checkDaemon() {
# Check to see if the daemon is running.
# This is a different function than statusDaemon
# so that we can use it other functions.
if [ -z "$oldPid" ]; then
return 0
elif [[ `ps aux | grep "$oldPid" | grep "$daemonName" | grep -v grep` > /dev/null ]]; then
if [ -f "$pidFile" ]; then
if [[ `cat "$pidFile"` = "$oldPid" ]]; then
# Daemon is running.
# echo 1
return 1
else
# Daemon isn't running.
return 0
fi
fi
elif [[ `ps aux | grep "$daemonName" | grep -v grep | grep -v "$myPid" | grep -v "0:00.00"` > /dev/null ]]; then
# Daemon is running but without the correct PID. Restart it.
log '*** '`date +"%Y-%m-%d"`": $daemonName running with invalid PID; restarting."
restartDaemon
return 1
else
# Daemon not running.
return 0
fi
return 1
}
loop() {
# This is the loop.
now=`date +%s`
if [ -z $last ]; then
last=`date +%s`
fi
# Do everything you need the daemon to do.
doCommands
# Check to see how long we actually need to sleep for. If we want this to run
# once a minute and it's taken more than a minute, then we should just run it
# anyway.
last=`date +%s`
# Set the sleep interval
if [[ ! $((now-last+runInterval+1)) -lt $((runInterval)) ]]; then
sleep $((now-last+runInterval))
fi
# Startover
loop
}
log() {
# Generic log function.
echo "$1" >> "$logFile"
}
###############################################################
# Parse the command.
###############################################################
if [ -f "$pidFile" ]; then
oldPid=`cat "$pidFile"`
fi
checkDaemon
case "$1" in
start)
startDaemon
;;
stop)
stopDaemon
;;
status)
statusDaemon
;;
restart)
restartDaemon
;;
*)
echo "Error: usage $0 { start | stop | restart | status }"
exit 1
esac
exit 0
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....
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"