if source command.sh issue
Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-redhat-linux-gnu' -DCONF_VENDOR='redhat' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I. -I./include -I./lib -D_GNU_SOURCE -DRECYCLES_PIDS -DDEFAULT_PATH_VALUE='/usr/local/bin:/usr/bin' -DSYSLOG_HISTORY -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -Wno-parentheses -Wno-format-security uname output: Linux morsh.c.edafarm-workstations-prod.internal 4.18.0-513.11.1.el8_9.0.1.x86_64 #1 SMP Sun Feb 11 10:42:18 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux Machine Type: x86_64-redhat-linux-gnu Bash Version: 4.4 Patch Level: 20 Release Status: release Description: script.sh contain: if source command.sh ; then echo pass else echo fail fi command.sh contain 'set -e' at start. so command.sh should exit once detect fail. once calling ./script.sh it look like command.sh dont handle 'set -e' correctly and it continue the script till the end anyway. (btw, it works correctly at version 4.2.46(2)-release (x86_64-redhat-linux-gnu) Repeat-By: [Describe the sequence of events that causes the problem to occur.] Fix: [Description of how to fix the problem. If you don't know a fix for the problem, don't include this section.]
Re: Feature request: process title with exec -a "" for oneself
On 8/31/24 10:43 PM, Lockywolf wrote: Dear Bash developers, May I ask for a small feature to be added to bash? At the moment exec changes IO redirections for the newly started processes, but if there is no command for exec'ing, it changes those redirections for the bash process itself. The exec -a, however, allows setting the current process title (argv0) only for the newly exec'ed processes, and "exec -a whatever" (without a command) does nothing. However it seems to be possible (albeit in a series of 8 syscalls) to change the _current_ process' cmdline and argv0: Currently, the shell's argc/argv are exposed to the user as $1...$n - the positional parameters (argv[1]...argv[argc]) $# - the number of positional parameters (argc) $0 - argv[0] You can change the positional parameters and $# using the `set' builtin, and, in bash versions newer than bash-4.4, you can change $0 by assigning to BASH_ARGV0. So I assume that you want to change the kernel's idea of the process arguments as seen and displayed by `ps'. If so, I'm not really interested in adding that as a feature. It doesn't seem to add anything for shell users. -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/ OpenPGP_signature.asc Description: OpenPGP digital signature
Re: if source command.sh issue
Date:Wed, 24 Jul 2024 13:22:07 + (UTC) From:morshalev@morsh.c.edafarm-workstations-prod.internal Message-ID: <20240904151336.D40A9142EBC@morsh.c.edafarm-workstations-prod.internal> There is no bug here. | if source command.sh ; then | command.sh contain 'set -e' at start. so command.sh should exit once detect fail. Once again, -e is bizarre, and stupid, and really shouldn't be used almost anywhere. Here the issue is that when a command is run as the condition of an "if" -e doesn't apply (you wouldn't want it to). What people fail to understand is that this applies to absolutely everything in a function, or source'd script - -e simply does not apply if you use it in a context like that (or one of the others where -e is inapplicable). Just find another way, avoid -e, you'll waste much less time than attempting to fight against the -e rules in order to save yourself some effort checking that everything which should work does work. The latter seems like it should be harder when you start out ("-e will just solve all that") but it *never* turns out that way. kre
Re: Feature request: process title with exec -a "" for oneself
I think your idea of using exec -a '' with no positional arguments to set it is pretty cool, since exec -a changes the argv[0] of the invoked process and exec with redirections an no arguments applies redirections to the current shell permanently! Not super relevant, but I have a bash loadable builtin that can set the script's proctitle that I wrote for fun ~1 year ago. It has to use an hack to figure out the right offset of argv[0]: it abuses the fact that the global variable shell_name is always set to a pointer that is an offset into argv[0], so walking backwards from it until a NUL is reached finds the start of argv[0]. But, otherwise, it works fairly well; you can also unload it to restore the original proctitle (enable -d setproctitle), and reload it to change it again. I was aware of the prctl(PR_SET_MM_ARG_{START,END}) approach, but I have never personally tried it. It does sound like a cleaner approach though, especially since bash doesn't easily expose argv[0], and we have to resort to an hack to find it; perhaps you could write your own loadable builtin that uses that. ^^ I left my loadable builtin at the bottom of the email. o/ emanuele6 Build with: make CFLAGS="$(pkg-config --libs --cflags bash) -shared" setproctitle Load with enable -f ./setproctitle setproctitle setproctitle.c #include #include #include #include #include #include #include static char *memstart = NULL; static char *memend = NULL; static char *memstart_copy = NULL; static char *original_shell_name = NULL; static size_t count_bytes(char const *const path) { size_t size = 0; int fd; do { fd = open(path, O_RDONLY); } while (fd < 0 && errno == EINTR); if (fd < 0) { builtin_warning("%s: Open error: %s", path, strerror(errno)); return size; } ssize_t nread; do { char buf[PIPE_BUF]; nread = read(fd, buf, sizeof buf); if (nread > 0) size += nread; } while (nread > 0 || (nread != 0 && errno == EINTR)); if (nread < 0) builtin_warning("%s: Read error: %s", path, strerror(errno)); int ret; do { ret = close(fd); } while (ret < 0 && errno == EINTR); if (ret < 0) builtin_warning("%s: Close error: %s", path, strerror(errno)); return size; } int setproctitle_builtin_load(char const *const name) { (void)name; /* shell_name is always an offset into argv[0] */ memstart = shell_name; /* find the start of argv[0]; linux seems fine with this approach */ while (memstart[-1]) --memstart; /* save and copy shell_name to the heap */ memstart_copy = savestring(memstart); original_shell_name = shell_name; shell_name = &memstart_copy[shell_name - memstart]; /* figure out size of usable memory counting bytes in /proc/self/cmdline and /proc/self/environ */ memend = memstart; memend += count_bytes("/proc/self/cmdline"); memend += count_bytes("/proc/self/environ"); /* fallback to length of argv[0] in case that does not work... */ if (memend == memstart) memend += strlen(memstart) + 1; return 1; } void setproctitle_builtin_unload(char const *const name) { (void)name; /* restore shell_name */ (void)strcpy(memstart, memstart_copy); shell_name = original_shell_name; xfree(memstart_copy); } static int setproctitle_builtin(WORD_LIST *list) { if (no_options(list)) return EX_USAGE; list = loptend; (void)memset(memstart, 0, memend - memstart); char *memused = memstart; for (WORD_LIST const *l = list; l; l = l->next) { size_t const maxlen = memend - memused - 1; char const *const arg = l->word->word; size_t const len = strlen(arg); if (len > maxlen) { builtin_warning("Too long, trimming..."); (void)memcpy(memused, arg, maxlen); break; } (void)memcpy(memused, arg, len); memused += len; } return EXECUTION_SUCCESS; } static char *setproctitle_doc[] = { "Changes the shell's proctitle", "", "If multiple arguments are passed, they are concatenated.", "", "Exit Status:", "Always returns 0 if the command is valid.", NULL, }; struct builtin setproctitle_struct = { "setproctitle", setproctitle_builtin, BUILTIN_ENABLED, setproctitle_doc, "setproctitle [title ...]", 0, };