Running with sudo
In general it is a bad idea to run arbitrary programs with sudo,
specially programs that are for verification like byexample.
However there are cases that it is required.
Running a single command with sudo (passwordless version)
For example you may need to run some code in a privileged shell,
like the following:
$ sudo test/ds/script-requires-root.sh # byexample: +skip
Checking <...>
Done.
That will work only if sudo does not ask a password.
You can achieve this making test/ds/script-requires-root.sh
passwordless editing you sudoers file with visudo and adding the
following line:
john ALL=(root) NOPASSWD: /home/john/full-path-here/test/ds/script-requires-root.sh
This tells sudo to not ask for a password (NOPASSWD) when the user
john is trying to execute the program
/home/john/full-path-here/test/ds/script-requires-root.sh to run it as
root.
Running a single command with sudo (password version)
Now you could run sudo and let it to ask for a password and you
could type the password in from byexample using
+type but you need to realize that
that would mean that you are typing your password in from of all your
readers:
$ sudo test/ds/script-requires-root.sh # byexample: +type +skip
<...>password for john: [your-plain-text-password-here]
Checking <...>
Done.
A preferible approach could have the password in an environment variable
named PASS and paste it with
+paste:
$ sudo test/ds/script-requires-root.sh # byexample: +paste +type +skip
<...>password for user: [<PASS>]
Checking <...>
Done.
Then, you should run byexample passing that PASS variable and
capturing the environment
so the variable is available in the example and be pasted into.
Something like this:
$ PASS=johnpasswordhere byexample -l shell --capture-env-var PASS test/ds/doc-with-sudo.md # byexample: +skip
[PASS] Pass: 1 Fail: 0 Skip: 0
Uncertainty due sudo caching the password
Passing a password will work but beware.
The example where you are typing the password (with or without having it
pasted from PASS) depends on sudo asking the password in the first
place.
sudo caches the password and subsequent calls to sudo will not
ask for the password again. But this cache expires after a while (in my
system is after 15 minutes).
If you have a long running examples, this may cause you some troubles
as you could not tell when a call to sudo will or will not ask for a
password.
To be certain you could call sudo -k to clean up the cache and be sure
that the next call to sudo will ask you a password.
Running the entire shell with sudo
If instead of having to run a few commands as root you need an entire
shell session, you can pass sudo in the
shebang:
$ byexample -l shell -x-shebang 'shell:%e sudo %p %a' test/ds/doc-without-sudo.md # byexample: +skip
[PASS] Pass: 1 Fail: 0 Skip: 0
This simplifies your documentation avoiding all the sudo calls but
there is a catch.
At the moment byexample does not support passing passwords to the
shebang so you will have to make the shell program (typically bash)
passwordless.
If making any sudo bash passwordless scares you (and it should!),
we can lower slightly the risk with an auxiliary script that opens bash (or other
shell supported by byexample):
#!/bin/sh
bash "$@"
We make the auxiliary script open-bash.sh passwordless editing
sudoers:
john ALL=(root) NOPASSWD: /home/john/full-path-here/test/ds/open-bash.sh
With this only sudo test/ds/open-bash.sh will be passwordless, other
calls to sudo bash will require a password as usual.
Finally we tell byexample to use that script instead of bash:
$ byexample -l shell -x-shebang 'shell:%e sudo test/ds/open-bash.sh %a' test/ds/doc-without-sudo.md # byexample: +skip
[PASS] Pass: 1 Fail: 0 Skip: 0
The advantage is that we can create
/home/john/full-path-here/test/ds/open-bash.sh before running
byexample and delete it after. Assuming that you don’t allow anyone
else to create the file, this is relatively safe.
If you have trouble with this or you feel that byexample is missing a
feature, don-t be afraid and open an issue in Github.