0

macOS High Sierra, 10.13.3 (17D102)

  • If I run in terminal sysctl -n hw.memsize it works fine, I get a number
  • If i run which sysctl i get /usr/sbin/sysctl which seems correct

How to run the same command from shell script? Looking for cross-OS solution. Using pure sh everywhere.

I have tried:

#!/bin/sh
$("sysctl -n hw.memsize")
exit 1

1 Result: line 2: sysctl -n hw.memsize: command not found

#!/bin/sh
$("/usr/sbin/sysctl -n hw.memsize")
exit 1

2 Result: line 2: /usr/sbin/sysctl -n hw.memsize: No such file or directory

#!/bin/sh
echo `sysctl -n hw.memsize`
exit 1

3 Result: line 2: 17179869184: command not found

Not sure why command not found afte the correct output.

#!/bin/sh
eval "sysctl -n hw.memsize"
exit 1

4 Result: same as running in terminal: 17179869184 But i want to avoid eval.

While 4th works as epxected, it uses eval and i try to avoid it. 3rd seems almost correct and not sure why 2nd says no such file while it does exist.

sh script file has a+x chmod.

  • 1
    Don't use quotes inside $(...). It's treating the entire quoted string as the name of the command to run, because, well, that's what quotes mean to do. Here you don't even need the $(...) though, that's if you want to run a command in a subshell and get its stdout back as a string – Eric Renouf Mar 24 '18 at 12:09
3

Literally the same command inside a script should be exactly the same:

sysctl -n hw.memsize

Your tries concentrate more on $(…) syntax and I don't know why the need for $(…) in the first place. If you need it (e.g. let's store the result in a variable), then it should be like

memsize=$(sysctl -n hw.memsize)

without quotes inside the $(…).


$("sysctl -n hw.memsize")

1 Result: line 2: sysctl -n hw.memsize: command not found

It is because of quoting. Your shell treats the entire string as a single word, a single command (executable) to run; while your intention is to pass a command and two arguments. Without quotes you would get command not found anyway because the shell would try to evaluate (run in this case) the result of the inner command (this is what $(…) does), e.g. the result could be 17179869184. There's no 17179869184 command in your system, is there? Note this command not found would come from a different level than when you use quotes.

$("/usr/sbin/sysctl -n hw.memsize")

2 Result: line 2: /usr/sbin/sysctl -n hw.memsize: No such file or directory

Basically the same as above. Error message is different because of / in the "command" but the mechanism is the same.

echo `sysctl -n hw.memsize`

3 Result: line 2: 17179869184: command not found

This should work (it's awful code though). Are you sure it was not just `sysctl -n hw.memsize` without echo? This would be the same as "without quotes" case explained under your 1st result.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.