Reputation: 321
So basically, I'm looking for a way to make the below bash script work without an issue. Each of the commands actually works when tested individually, it's only in the actual script it has a problem. The code is below:
#!/bin/bash
answer="$(/usr/bin/grep "PermitRootLogin yes" /etc/ssh/sshd_config)"
if [ $answer ]; then
(perl -pi -e \'s/\"PermitRootLogin yes\"/\"PermitRootLogin no\"/g\' /etc/ssh/sshd_config)
else
echo "Root login is already not permitted, no values changed."
fi
Here's what happens when I try to run it:
test.sh: line 9: [: PermitRootLogin: unary operator expected
Root login is already not permitted, no values changed.
So basically, rather than it doing the find/replace as I want it to on the file via the perl command, it's trying to interpret it as a separate instruction.
All it is attempting to do is look at the /etc/ssh/sshd_config
file and then change the relevant entry from yes to no if the "answer" is found to be yes.
I'm basically looking for a way to make this work. I've looked at a lot of bash examples on this site but none of them seem to cover this specific case.
Also, the reason I'm using perl
is that sed
works very oddly on Solaris 11, or isn't installed on extremely old versions, and perl
is installed on every version from 8 forward.
Any ideas?
Upvotes: 1
Views: 135
Reputation:
Value of $(grep...)
is the lines found by grep or empty string. Using those lines as argument to [
is not too useful.
Try
if /usr/bin/grep "PermitRootLogin yes" /etc/ssh/sshd_config >/dev/null; then
instead.
How does it work?
The actual syntax for if
in bash (or sh, for that matter) is
if command args; then
When you use if [ ... ]
syntax, all you do is use [
as an alias for test
command (try running which [
on your machine).
if
takes the then
branch when command succeeds (has exit code of 0) and else
branch when it fails - returns non-zero exit code.
grep succeeds when pattern is found, fails when not found.
Upvotes: 1
Reputation: 53478
You could just run the replace, because if it's not necessary, it won't match and it won't do anything.
This is exactly as efficient as grep
ing the file first.
If you need a message, how about counting whether it actually did it:
perl -i.bak -pe '$result += s/PermitRootLogin yes/PermitRootLogin no/; END { exit 1 unless $result }' /etc/ssh/sshd_config
(Then test $?
in your script).
Or:
perl -i.bak -pe '$result += s/PermitRootLogin yes/PermitRootLogin no/; END { print "Fixed permissions\n" if $result }' /etc/ssh/sshd_config
Upvotes: 1
Reputation: 241818
Double quote the variable in square brackets.
if [ "$answer" ] ; then
Otherwise, it's expanded and word-split, but [
doesn't know what to do with two words (it expects the first one to be a unary operator like -f
which is what the error's telling you).
Upvotes: 2