Use ld -soname
:
$ mkdir dir1 dir2
$ gcc -shared -fPIC -o dir1/func.so func1.c -Wl,-soname,func.so
$ gcc -shared -fPIC -o dir2/func.so func2.c -Wl,-soname,func.so
$ gcc test.c dir1/func.so
$ ldd a.out
linux-vdso.so.1 => (0x00007ffda80d7000)
func.so => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f639079e000)
/lib64/ld-linux-x86-64.so.2 (0x00007f6390b68000)
$ LD_LIBRARY_PATH='$ORIGIN/dir1:$ORIGIN/dir2' ./a.out
hello world
$ LD_LIBRARY_PATH='$ORIGIN/dir2:$ORIGIN/dir1' ./a.out
No print
-Wl,-soname,func.so
(this means -soname func.so
is passed to ld
) embeds SONAME
attribute of func.so
in the output. You can examine it by readelf -d
:
$ readelf -d dir1/func.so
Dynamic section at offset 0xe08 contains 25 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000e (SONAME) Library soname: [func.so]
...
Linked with this func.so
with SONAME
, a.out
has that in its NEEDED
attribute:
$ readelf -d a.out
Dynamic section at offset 0xe18 contains 25 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [func.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
...
Without -Wl,-soname,func.so
, you'll get the following by readelf -d
:
$ readelf -d dir1/func.so
Dynamic section at offset 0xe18 contains 24 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
...
$ readelf -d a.out
Dynamic section at offset 0xe18 contains 25 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [dir1/func.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
...
Then answer is that sudo
has a bug. First, the workaround: I put this in my /etc/sudoers.d/zabbix file
:
zabbix ALL=(root) NOPASSWD: /bin/env SHELL=/bin/sh /usr/local/bin/zabbix_raid_discovery
and now subcommands called from zabbix_raid_discovery
work.
A patch to fix this will be in sudo 1.8.15. From the maintainer, Todd Miller:
This is just a case of "it's always been like that". There's not
really a good reason for it. The diff below should make the behavior
match the documentation.
- todd
diff -r adb927ad5e86 plugins/sudoers/env.c
--- a/plugins/sudoers/env.c Tue Oct 06 09:33:27 2015 -0600
+++ b/plugins/sudoers/env.c Tue Oct 06 10:04:03 2015 -0600
@@ -939,8 +939,6 @@
CHECK_SETENV2("USERNAME", runas_pw->pw_name,
ISSET(didvar, DID_USERNAME), true);
} else {
- if (!ISSET(didvar, DID_SHELL))
- CHECK_SETENV2("SHELL", sudo_user.pw->pw_shell, false, true);
/* We will set LOGNAME later in the def_set_logname case. */
if (!def_set_logname) {
if (!ISSET(didvar, DID_LOGNAME))
@@ -984,6 +982,8 @@
if (!env_should_delete(*ep)) {
if (strncmp(*ep, "SUDO_PS1=", 9) == 0)
ps1 = *ep + 5;
+ else if (strncmp(*ep, "SHELL=", 6) == 0)
+ SET(didvar, DID_SHELL);
else if (strncmp(*ep, "PATH=", 5) == 0)
SET(didvar, DID_PATH);
else if (strncmp(*ep, "TERM=", 5) == 0)
@@ -1039,7 +1039,9 @@
if (reset_home)
CHECK_SETENV2("HOME", runas_pw->pw_dir, true, true);
- /* Provide default values for $TERM and $PATH if they are not set. */
+ /* Provide default values for $SHELL, $TERM and $PATH if not set. */
+ if (!ISSET(didvar, DID_SHELL))
+ CHECK_SETENV2("SHELL", runas_pw->pw_shell, false, false);
if (!ISSET(didvar, DID_TERM))
CHECK_PUTENV("TERM=unknown", false, false);
if (!ISSET(didvar, DID_PATH))
Best Answer
On Red Hat and CentOS systems, it is defined in
/etc/profile.d/less.sh
. On version 5, this containsOn other systems, such as version 7, the value may be
||/usr/bin/lesspipe.sh %s
; there is a slightly different interpretation between values that begin with|
and||
, detailed in the man page for less.You can either edit that file if you want all users of bash-like shells on your system to see a different value, or override it for yourself by editing
~/.bashrc
or~/.bash_profile
to have anexport LESSOPEN=whatever
line.On Linux systems,
grep -r string /
orgrep -R string /
may run into problems when reading certain special files.grep
will hang when reading/dev/rfkill
, and, due to what I believe is a buffer allocation bug, will run out of memory reading certain large files in/proc
. An alternative is to exclude/dev
and/proc
: