Sample Header Ad - 728x90

Unix & Linux Stack Exchange

Q&A for users of Linux, FreeBSD and other Unix-like operating systems

Latest Questions

5 votes
2 answers
363 views
How to do indirect variable substitution in a GNU Makefile?
In the shell I can do ``` $ a=b b=c; eval echo \$$a c ``` How do I do the same with GNU Make's `$(eval)` function? ``` $ cat Makefile a=b b=c x:; echo {What goes here in order to get:} $ make c ```
In the shell I can do
$ a=b b=c; eval echo \$$a
c
How do I do the same with GNU Make's $(eval) function?
$ cat Makefile
a=b
b=c
x:; echo {What goes here in order to get:}
$ make
c
Dan Jacobson (560 rep)
Jun 30, 2025, 05:33 AM • Last activity: Jun 30, 2025, 06:55 AM
0 votes
1 answers
93 views
In Bash 5.2+, is there a means to read the command currently being evaluated?
...that is to say, is there a means by which I can read the full command that's being evaluated AS it's happening? Here's a contrived example, but one I feel makes the question clear: ```shell function showOwnEvaluation { local evaluatingCommand=???? [[ "$evaluatingCommand" =~ ^showOwnEvaluation ]]...
...that is to say, is there a means by which I can read the full command that's being evaluated AS it's happening? Here's a contrived example, but one I feel makes the question clear:
function showOwnEvaluation {
    local evaluatingCommand=????
    [[ "$evaluatingCommand" =~ ^showOwnEvaluation ]] && echo "Original Function"
}

alias sOE='showOwnEvaluation'

$ showOwnEvaluation 123
# Output: Original Function

$ sOE 123
# Output:
Basically the ability to run echo "$(!-1)" for the current, active command? A echo "$(!0)", if you will? What I'd like to accomplish here is this: if I'm assigning the result of an expansion to a variable:
someVar=$(myFunc)
...I'd like to be able to alter the response from myFunc *based on the name of the variable it's being set to*. I simply cannot figure out how to get the someVar= portion of the expression, if, indeed, it's even possible to DO such a thing (without slapping a full emulation over the terminal and monitoring all of the I/O, of course). I know this may seem like a nonsensical desire, here, but I actually do have a valid use-case. I'm just uncertain if it's even feasible.
NerdyDeeds (123 rep)
Jan 26, 2025, 12:53 AM • Last activity: Jan 26, 2025, 03:49 PM
339 votes
11 answers
901074 views
What is the "eval" command in bash?
What can you do with the `eval` command? Why is it useful? Is it some kind of a built-in function in bash? There is no `man` page for it..
What can you do with the eval command? Why is it useful? Is it some kind of a built-in function in bash? There is no man page for it..
LanceBaynes (41465 rep)
Oct 22, 2011, 08:02 PM • Last activity: Jan 10, 2025, 05:40 PM
0 votes
1 answers
122 views
How to properly make eval safe?
I'm writing a shell script that changes its behavior based on the number of positional parameters passed # script.sh ```bash if [ $# -eq 1 ]; then if [ -f "$1" ]; then validate='validate <"$1"' else validate='validate <<<"$1"' fi else IFS=$'\n' validate="validate <<<'${*}'" fi eval "$validate" | pul...
I'm writing a shell script that changes its behavior based on the number of positional parameters passed # script.sh
if [ $# -eq 1 ]; then
  if [ -f "$1" ]; then
    validate='validate <"$1"'
  else
    validate='validate <<<"$1"'
  fi

else
  IFS=$'\n'
  validate="validate <<<'${*}'"
fi

eval "$validate" | pull_data
Both validate and pull_data are Bash functions that read from stdin and write to stdout If the first case [ $# -eq 1 ], I believe the code is safe from injection. Since the string is single-quoted, parameter expansion only happens after eval is called. I can't think of a string that could result in code injection here. ## Issue The problem arise with the else condition. Here, each positional parameters is expanded into a new line. For example
./script.sh "string_with_'_in_its_name" "code injected'"
The quote inside one of the first parameter causes subsequent new parameters to be interpreted as commands. Similarly, this also results in an injection vulnerability:
./script.sh valid_input \''$(code injected)'\'
## Context I'm using eval to avoid repeating the validate ... | pull_data construct in every if condition. The real script has many more conditions, and using eval makes it more readable. Any advice on how to refactor this script to avoid the injection issue while maintaining readability would be greatly appreciated!
killua148 (3 rep)
Jan 5, 2025, 06:46 PM • Last activity: Jan 7, 2025, 09:18 AM
0 votes
1 answers
93 views
eval for pathnames from mkdir -p
I am writing a script to move around a bit of data, which I want to be able to create the parent directory to where I am sending my data, in order to do some renaming/cleaning of filenames I need to keep track of the newly created directories so I can change the permissions to the set input argument...
I am writing a script to move around a bit of data, which I want to be able to create the parent directory to where I am sending my data, in order to do some renaming/cleaning of filenames I need to keep track of the newly created directories so I can change the permissions to the set input argument. Seeing as mkdir -vp can output the created directories it felt perfect, however, I am unable to dereference the quotes to be able to use the output, and eval seems the only option. I am aware that I could probably just loop and check if each directory exist, but it seems wasteful when mkdir outputs it already. This is my code as of now: readarray -t ndir < <(ssh myhost mkdir -vp foo/ | grep -oP "^mkdir: created directory\s+\K['\"].+['\"](?=$)" | sort -r) eval ndir=("${ndir[@]}") ssh myhost chmod 555 "${ndir[@]}" EDIT: If foo was a path with newlines, or other special character they will be quoted in $'..' format, which is why I started using eval. It is my understanding that eval is as close to evil as you can come, but I don't see any viable and as convenient solution other than manually looping over and checking which parts of the path exist. Is there a safer, and alternative way?
Caesar (25 rep)
Nov 21, 2024, 12:55 AM • Last activity: Nov 23, 2024, 08:52 AM
1 votes
0 answers
19 views
While Loop Exits After Calling Function
I'm trying to do a `db` backup script using `Bash`. When adding a "Resume" feature to the script, I do the following loop calling defined functions to do step by step (depending on the .lock file contents). This is unexpected behavior since I have created a bunch of other scripts that follow the sam...
I'm trying to do a db backup script using Bash. When adding a "Resume" feature to the script, I do the following loop calling defined functions to do step by step (depending on the .lock file contents). This is unexpected behavior since I have created a bunch of other scripts that follow the same logic on calling functions from a loop and they work correctly. My guess is it has something to do with the ssh command which is the difference throughout all the other scripts, but I just can't wrap my mind around it… ``` LOCK=restore.lock SERVER_BACKUP_FILE_NAME="backup" ... show_help() { ... } while getopts i:h opt; do case $opt in i) COMPANY_ID=$OPTARG;; h) show_help esac done ... backup() { if [ ! -z $COMPANY_ID ] then log_echo "Creating company backup file from production..." sleep 5 SOURCE_SERVER_IP=$(dig +short ${SOURCE_SERVER_HOST}) REMOTE_CMD="~/repository/scripts/database/backup.sh -i ${COMPANY_ID}; exit;" ssh ${SOURCE_SERVER_USER}@${SOURCE_SERVER_IP} "bash -l -c '${REMOTE_CMD}'" SERVER_BACKUP_FILE_NAME="backup_${COMPANY_ID}" fi sed "/\/d" -i ${LOCK} } download() { ... } import() { ... } # For some reason the backup() function breaks the while loop. restore() { while IFS= read -r FUNC; do eval $FUNC; done > ${LOCK} echo "download" >> ${LOCK} echo "import" >> ${LOCK} else log_echo "Resuming..." fi # Calling main function that loops through the .lock file containing the function names # to dynamically execute said functions. restore
James (111 rep)
Jul 19, 2024, 02:46 AM • Last activity: Jul 19, 2024, 03:03 AM
0 votes
2 answers
136 views
Confusing results of eval + sed combination
I run a game from steam which starts with the game companies launcher app where I have to click another button to start the actual game. The game launcher is very slow, contains needless advertising, which I should not be forced to experience as I paid for the game in it's entirety, it is not a free...
I run a game from steam which starts with the game companies launcher app where I have to click another button to start the actual game. The game launcher is very slow, contains needless advertising, which I should not be forced to experience as I paid for the game in it's entirety, it is not a free online game *paid for by advertising*, and it sends my telemetry to different servers around the world! Someone provided some simple code in a community guide to bypass the launcher but I cannot get it to work for reasons that make no sense to me. Their simple code is to put this command in steam's properties for the game which works for them and other users eval $( echo “%command%” | sed -E “s#Launcher/dowser.exe#Cities2.exe#g” ) But nothing happens when I start the game in steam, it just exits after 30 seconds or so. So I added **tee** to the command to see what sed ouputs, like this eval $( echo “%command%” | sed -E “s#Launcher/dowser.exe#Cities2.exe#g” | tee ~/foot.txt) And foo.txt is empty, which makes no sense because if I run this command eval $( echo “%command%” | foo.bash ) Which is this script #/bin/bash echo "$*" > ~/foo.txt Then foo.txt has the expected command line received by bash on STDIN that sed should be receiving. So then I ran the same sed command with the --debug switch and get this output in a log SED PROGRAM: s/Launcher\/dowser.exe/Cities2.exe/g INPUT: 'STDIN' line 1 PATTERN: /home/user/.local/share/Steam/ubuntu12_32/reaper SteamLaunch AppId=949230 -- /home/user/.local/share/Steam/ubuntu12_32/steam-launch-wrapper -- '/home/user/.local/share/Steam/steamapps/common/SteamLinuxRuntime_sniper'/_v2-entry-point --verb=waitforexitandrun -- '/home/user/.local/share/Steam/steamapps/common/Proton 8.0'/proton waitforexitandrun '/home/user/.local/share/Steam/steamapps/common/Cities Skylines II/Launcher/dowser.exe' COMMAND: s/Launcher\/dowser.exe/Cities2.exe/g MATCHED REGEX REGISTERS regex = 409-428 'Launcher/dowser.exe' PATTERN: /home/user/.local/share/Steam/ubuntu12_32/reaper SteamLaunch AppId=949230 -- /home/user/.local/share/Steam/ubuntu12_32/steam-launch-wrapper -- '/home/user/.local/share/Steam/steamapps/common/SteamLinuxRuntime_sniper'/_v2-entry-point --verb=waitforexitandrun -- '/home/user/.local/share/Steam/steamapps/common/Proton 8.0'/proton waitforexitandrun '/home/user/.local/share/Steam/steamapps/common/Cities Skylines II/Cities2.exe' END-OF-CYCLE: /home/user/.local/share/Steam/ubuntu12_32/reaper SteamLaunch AppId=949230 -- /home/user/.local/share/Steam/ubuntu12_32/steam-launch-wrapper -- '/home/user/.local/share/Steam/steamapps/common/SteamLinuxRuntime_sniper'/_v2-entry-point --verb=waitforexitandrun -- '/home/user/.local/share/Steam/steamapps/common/Proton 8.0'/proton waitforexitandrun '/home/user/.local/share/Steam/steamapps/common/Cities Skylines II/Cities2.exe' So sed is receiving the expected data from steam on STDIN, and the sed commandline script is producing the expected result, but inexplicably eval is not recieving the sed output or not executing it. Then just to see what happens, I ran the same command again but chained the sed output from the debug log after the sed command, so the result and output from sed would be thrown away, and the appended command would be run, like this eval $( echo “%command%” | sed -E “s#Launcher/dowser.exe#Cities2.exe#g” & /home/user/.local/share/Steam/ubuntu12_32/reaper SteamLaunch AppId=949230 -- /home/user/.local/share/Steam/ubuntu12_32/steam-launch-wrapper -- '/home/user/.local/share/Steam/steamapps/common/SteamLinuxRuntime_sniper'/_v2-entry-point --verb=waitforexitandrun -- '/home/user/.local/share/Steam/steamapps/common/Proton 8.0'/proton waitforexitandrun '/home/user/.local/share/Steam/steamapps/common/Cities Skylines II/Cities2.exe') And the game successfully runs without the launcher!!! I don't get it, why is eval not executing the sed output as the command, but does execute the command line that sed apparently does output when I chain it after the sed command? The only downside to that execution was that steam does not recognize that the game has closed when I exit it, but I could live with that. I am running on Ubuntu 23.10, using steam in X
nobody special (103 rep)
Dec 11, 2023, 04:24 PM • Last activity: Jan 28, 2024, 03:16 PM
4 votes
2 answers
16854 views
Handling long-options with getopts
I am parsing options with `getopts` but would like to handle long-options as well. print-args () { title="$1" ; shift printf "\n%s\n" "${title}: \$@:" for arg in "$@"; do (( i = i + 1 )) printf "%s |%s|\n" "${i}." "$arg" done } getopts_test () { aggr=() for arg in "$@"; do case $arg in ("--colour"|"...
I am parsing options with getopts but would like to handle long-options as well. print-args () { title="$1" ; shift printf "\n%s\n" "${title}: \$@:" for arg in "$@"; do (( i = i + 1 )) printf "%s |%s|\n" "${i}." "$arg" done } getopts_test () { aggr=() for arg in "$@"; do case $arg in ("--colour"|"--color") aggr+=( "-c" ) ;; ("--colour="*|"--color="*) aggr+=( "-c" "${arg#*=}" ) ;; (*) aggr+=( "$arg" ) ;; esac done print-args "print" "$@" eval set -- "${aggr[@]}" print-args "eval" "$@" set -- "${aggr[@]}" print-args "set" "$@" local OPTIND OPTARG local shortopts="C:" while getopts "$shortopts" arg; do case $arg in ("c") context="$OPTARG" ;; (*) break ;; esac done shift $(( OPTIND - 1 )) } But I wonder whether the use of set -- "${aggr[@]}" is correct. Or is the following (using eval) more appropriate? eval set -- "${aggr[@]}" I have performed a test shown below. With eval, the string "Gunga Din" is split up, whereas with set -- "${aggr[@]}", it is being parsed correctly as a single string. getopts_test -f -g 130 --colour="170 20" "Gunga Din" print: $@: 1. |-f| 2. |-g| 3. |130| 4. |--colour=170 20| 5. |Gunga Din| eval: $@: 1. |-f| 2. |-g| 3. |130| 4. |-c| 5. |170| 6. |20| 7. |Gunga| 8. |Din| set: $@: 1. |-f| 2. |-g| 3. |130| 4. |-c| 5. |170 20| 6. |Gunga Din| Then I ran another function that uses the non-GNU getopt. getopt_test () { shortopts="Vuhv::H::w::e::n::l::C:" shortopts="${shortopts}bgcrmo" longopts="version,usage,help,verbosity::" longopts="${longopts},heading::,warning::,error::" longopts="${longopts},blu,grn,cyn,red,mgn,org" opts=$( getopt -o "$shortopts" -l "$longopts" -n "${0##*/}" -- "$@" ) print-args "\$@:" "$@" print-args "opts:" "$opts" set -- "$opts" print-args "set -- \"$opts\"" "$@" eval set -- "$opts" print-args "eval set -- \"$opts\"" "$@" } This resulted in the following getopt_test --warning=3 "foo'bar" "Gunga Din" $@: 1. |--warning=3| 2. |foo'bar| 3. |Gunga Din| opts: 1. | --warning '3' -- 'foo'\''bar' 'Gunga Din'| set -- "$opts" 1. | --warning '3' -- 'foo'\''bar' 'Gunga Din'| eval set -- "$opts" 1. |--warning| 2. |3| 3. |--| 4. |foo'bar| 5. |Gunga Din| As shown the result of getopt is a single entry with positional arguments re-arranged. This shows the need to use eval set -- "$opts" to split the positional arguments in the opts string into five entries for option parsing and processing.
Vera (1363 rep)
Oct 30, 2021, 09:46 AM • Last activity: Dec 18, 2023, 04:43 PM
0 votes
2 answers
564 views
eval: $? vs ${PIPESTATUS[@]} (bash)
In bash 5.0, I wish to capture the `${PIPESTATUS[@]}` of a piped command that is executed via `eval`. However, `eval` appears to mask `${PIPESTATUS[@]}`, but doesn't mask `$?` which is the equivalent to `${PIPESTATUS[-1]}`. Is there a way to extract `${PIPESTATUS[@]}` from the results of `eval`? App...
In bash 5.0, I wish to capture the ${PIPESTATUS[@]} of a piped command that is executed via eval. However, eval appears to mask ${PIPESTATUS[@]}, but doesn't mask $? which is the equivalent to ${PIPESTATUS[-1]}. Is there a way to extract ${PIPESTATUS[@]} from the results of eval? Appending something to the commandstring below like && array=( ${PIPESTATUS[@]} ) && export array does not appear to work. Am I correct in assuming from this that $? is not simply ${PIPESTATUS[-1]}? My sample code (ran as root): #!/usr/bin/env bash #without eval, ${PIPESTATUS[@]} has two entries as it should. apt-get install -y java-17-openjdk-amd64 2>&1 | tee -a ~/log commandsPipestatus=( ${PIPESTATUS[@]} ) for status in ${commandsPipestatus[@]}; do echo $status done echo "" echo "" #with eval, ${PIPESTATUS[@]} has one entry and is equal to $? commandstring="apt-get install -y java-17-openjdk-amd64 2>&1 | tee -a ~/log" eval "$commandstring" commandsPipestatus=( ${PIPESTATUS[@]} ) for status in ${commandsPipestatus[@]}; do echo $status done EDIT: Fixed a small technical correction in my original statement about PIPESTATUS. Also, based on the answers below, here are some clarifications: - I'm using eval because I'm building command strings programmatically and some of them may contain bash -c... which run the command as different users. - I looked at setting pipefail and that may work sometimes though not always because sometimes I need to know the status of multiple steps in the pipe. If I could set set -o pipefail and then unset it after that could work, but I'm not seeing how to unset pipefail and I can't simply exit the subshell and then continue in a new one where pipefail is not been set. How do I unset a shell option such as pipefail? - Is my above understanding of how to export an array that contains PIPESTATUS incorrect? How can I simply export PIPESTATUS from the eval subshell? EDIT 2: Thanks to the excellent answer marked below, my final decision was for the case where I am dynamically assembling command strings that include redirection (which is why I need eval), I would use set -o pipefail and then after execution do set +o pipefail. I'm also re-researching best practices for executing dynamically built commands, as I have several years more bash experience since the last time I did. My use cases for eval are: 1. Commands may contain bash -c, so I can't use bash -c to execute them 2. May contain redirection, such as >> log 3. The dynamical commands may also have arguments added to them for debugging purposes As far as I can tell, I may be able to do things differently for 1, and for 3 I should be using things like set -x [command] and trap instead. I have yet to find a solution for 2.
jitter (5 rep)
Oct 15, 2023, 06:29 AM • Last activity: Oct 23, 2023, 06:47 AM
0 votes
1 answers
1103 views
Sanitize input that is used to update script
Looking at a bash-script that takes input from Git commit comment to update itself. Simplified: `script`: ```sh #!/bin/bash comment='' printf '%s\n' "$comment" upgrade_script() { # Download latest: curl -o updated_script https://path/to/file # Get comment: new_comment="$(curl https://path/to/comment...
Looking at a bash-script that takes input from Git commit comment to update itself. Simplified: script:
#!/bin/bash

comment=''

printf '%s\n' "$comment"

upgrade_script() {
        # Download latest:
        curl -o updated_script https://path/to/file 

        # Get comment:
        new_comment="$(curl https://path/to/comment) "

        # Update comment='' with new_comment:
        sed -i "3,0 s/comment=''/comment='$new_comment'/" updated_script
}
Issue is if comment has characters that either breaks sed or mangles bash. E.g:
# that's all she wrote!  => comment='that's all she wrote!
# use /need/ over /want/ => s/comment=''/'use /need/ over /want'/'
and then of course with the potential for both malicious but also unintended things like:
# Remove tmp files by: ' rm -r *;' => comment='Remove tmp files by: ' rm -r *;''
--- ## Would this be enough to battle the issue? Add this before the sed -i command:
new_comment=$(
    sed \
    -e "s/'/'\"'\"'/g" \
    -e 's/[&\\/]/\\&/g; s/$/\\/; $s/\\$//'<<< "$new_comment"
)
For bash: 1) Replace ' with '"'"'. For sed: 1) Escape &, \, / and line-terminators. or what would be the faults? ---- Ideally this would not be done at all but curious to know. ### *Side comment:* Another solution, *to keep it in one file*, could be to add an exit in the script and add the text after that, then use sed or the like to print it. But that is beside my question.
#!/bin/bash

code
code
code

# When in need of the comment:
sed -n '/^exit # EOF Script$/$ {/start_xyz/,/end_xyz/ ...}'
# or what ever. Could even record offset and byte-length safely

code
code

exit # EOF Script

start_xyz
Blah blah blah
blaah
end_xyz
And thinking of it I guess something in the realm of:
comment=<<<'SOF'
...
SOF
Where one only need to replace any SOF to not end prematurely. Still my question is the*sanitizing* above. Thanks.
Err488 (25 rep)
Jun 26, 2023, 06:59 PM • Last activity: Jun 27, 2023, 06:02 AM
0 votes
1 answers
78 views
Shell script: Using variables makes command fails ( substituting values of variables manually ; command works fine )
In a bash script: jenkins_folder=`cut -d "|" -f1 -s input.csv` jenkins_url='https://url.com:8181/jenkins/view/' echo "jenkins_folder : ${jenkins_folder}" for job in `java -jar jenkins-cli.jar -s ${jenkins_url}${jenkins_folder} list-jobs ${jenkins_folder} ` do echo "Job name:: ${job} ****" java -jar...
In a bash script: jenkins_folder=cut -d "|" -f1 -s input.csv jenkins_url='https://url.com:8181/jenkins/view/ ' echo "jenkins_folder : ${jenkins_folder}" for job in java -jar jenkins-cli.jar -s ${jenkins_url}${jenkins_folder} list-jobs ${jenkins_folder} do echo "Job name:: ${job} ****" java -jar jenkins-cli.jar -s ${jenkins_url}${jenkins_folder} get-job ${job} > job.xml done is giving following output jenkins_folder : Platform-X.X.X-SPO-MyPD-Integration-Dummy ****ame:: NH-AccountManagementAudit-Consumer-MyPD-Integration-DUMMY-Reporting '; perhaps you meant 'NH-AccountManagementAudit-Consumer-MyPD-Integration-DUMMY-Reporting'? And when I substitute values of all variables and run following command; it works fine java -jar jenkins-cli.jar -s https://url.com:8181/jenkins/view/Platform-X.X.X-SPO-MyPD-Integration-Dummy get-job NH-AccountManagementAudit-Consumer-MyPD-Integration-DUMMY-Reporting > job.xml I have wasted too much time on this. I even tried using eval function but no luck. Please help. Thanks to @Kusalananda when I am trying to echo job name its printing output in wierd fashion.. I feel this is the root cause.. but not sure why that is happening If I try to shorten the length of variable job (using substring); then it prints fine. Hence, if value of job is long; it is creating problem
Deepak Singhal (103 rep)
Apr 24, 2023, 10:55 AM • Last activity: Apr 24, 2023, 12:21 PM
4 votes
4 answers
709 views
awk or perl to eval mathematical expressions in each line
I want a script to make awk to become an interactive mathematical calculator, to eval mathematical expressions given in each line. I.e., instead of constructing awk commands to calculate expressions like the following: ``` $ awk 'BEGIN{print 180/1149}' 0.156658 $ awk 'BEGIN{print (150+141)/1149}' 0....
I want a script to make awk to become an interactive mathematical calculator, to eval mathematical expressions given in each line. I.e., instead of constructing awk commands to calculate expressions like the following:
$ awk 'BEGIN{print 180/1149}'
0.156658

$ awk 'BEGIN{print (150+141)/1149}'
0.253264
I want my script to take my mathematical expressions as input and do the calculation interactively. So the session will look like (alternative of input and output):
180/1149
0.156658
(150+141)/1149
0.253264
1 + 2
3
2 * 3 - 5
1
However I'm not able to do that myself:
$ awk '{print}'
180/1149
180/1149
^C

$ awk '{print $0}'
180/1149
180/1149
1 + 2
1 + 2
^C
If there is no simple solution to awk, what else, like perl?
xpt (1858 rep)
Mar 24, 2023, 04:53 PM • Last activity: Mar 25, 2023, 12:00 PM
1 votes
1 answers
1148 views
Command output evaluation not working in Bash script
I am trying to automate adding Homebrew to my path in a shell script, but these two lines do not evaluate inside my shell script: ```bash #!/bin/sh eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" ``` The second line of code runs the program `[home]brew` with [the argument `shellenv`](https://...
I am trying to automate adding Homebrew to my path in a shell script, but these two lines do not evaluate inside my shell script:
#!/bin/sh
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
The second line of code runs the program [home]brew with [the argument shellenv](https://github.com/Homebrew/brew/blob/master/Library/Homebrew/cmd/shellenv.sh) . It echoes several environment variables to set which are then evaluated. The first line just adds the second line to my ~/.profile so brew's PATH is setup in every shell. I noticed that this statement does not work in my shell script, ***but*** it does when I type it into my terminal. What might be causing this? I tried running the commands I was instructed to run after Homebrew installed in a shell script and got the same behavior. **similar question:** - [problem with homebrew installation path on linux](https://unix.stackexchange.com/questions/713835/problem-with-homebrew-installation-path-on-linux)
unrealapex (132 rep)
Feb 16, 2023, 01:37 AM • Last activity: Feb 19, 2023, 08:41 AM
-1 votes
1 answers
97 views
use a variable as a variable
I'd like to use a variable `variablenaam` for using in a loop. I tried for hours but can't make it work. My experiment in bash on a RPi 4 with the latest Raspbian. I like to make the use of xstack1 and xstack2 variable so i can use them in a loop. Example below has two stacks I like to use in a loop...
I'd like to use a variable variablenaam for using in a loop. I tried for hours but can't make it work. My experiment in bash on a RPi 4 with the latest Raspbian. I like to make the use of xstack1 and xstack2 variable so i can use them in a loop. Example below has two stacks I like to use in a loop so I have to make the variable xstack variable. clear xstack1=( domoticz dashboard dashticz nodered ) xstack2=( x y z ) printf "Original value xstack1[*]= ${xstack1[*]}" # this gives all the entries of x, this must be the result at the end by choose for xstack1 = q=1 printf "\n\n Lets Start, try to make xstack variable" q=1 # we want tot retrieve all values of xstack1 qq=$(eval "echo xstack${q}") printf "\nvariablenaame of xstack1 = $qq" # so far so good printf "\n" qqq=$(eval "echo $qq[*]") #now add the all parameter printf "\nvariablenaam with wildcard must do show all values but dont= $qqq" #only one value printf "\n\n" qqqq=$(eval "echo \$$qqq") printf "last try and does not work, i only get one value= ${qqqq}\n" This is The code where i want to use it. you see for similar block with stack1-4 and i think this can be one block with a variable name for xstack1-4. This xstack is a array and i think that gives the problem. These blocks are working perfectly, but not written perfectly :-) local t_maxkolom=9 local t_mitem=1 local t_stack=0 while [ $t_stack -lt $t_maxkolom ] do local t_gitem=0 local t_sp='%31s' if [ -z "${stack1[$t_stack]}" ]; then printf $t_sp && printf "${normal}"; else printf "${number} $((t_mitem + $t_gitem )))${normal} Toevoegen " && printf '%-16s' "${stack1[$t_stack]}" && printf "${normal}" fi local t_sp='%32s' local t_gitem=$((t_gitem + 10)) if [ -z "${stack2[$t_stack]}" ]; then printf $t_sp && printf "${normal}"; else printf "${number} $((t_mitem + $t_gitem )))${normal} Toevoegen " && printf '%-16s' "${stack2[$t_stack]}" && printf "${normal}" fi local t_sp='%32s' local t_gitem=$((t_gitem + 10)) if [ -z "${stack3[$t_stack]}" ]; then printf $t_sp && printf "${normal}"; else printf "${number} $((t_mitem + $t_gitem )))${normal} Toevoegen " && printf '%-16s' "${stack3[$t_stack]}" && printf "${normal}" fi local t_sp='%32s' local t_gitem=$((t_gitem + 10)) if [ -z "${stack4[$t_stack]}" ]; then printf $t_sp && printf "${normal}\n"; else printf "${number} $((t_mitem + $t_gitem )))${normal} Toevoegen " && printf '%-16s' "${stack4[$t_stack]}" && printf "${normal}" printf "\n" fi t_stack=$(( $t_stack + 1 )) t_mitem=$((t_mitem + 1)) done With this code I generate the menu items for my docker app enter image description here
pvk (5 rep)
Feb 11, 2023, 03:50 PM • Last activity: Feb 15, 2023, 10:18 AM
0 votes
1 answers
397 views
Declare variable in eval Bash
There is a way to declare variable in eval ? For example function test { eval $1 } test " value="foo" echo "$value" " But it display nothing. Anyone can help please ?
There is a way to declare variable in eval ? For example function test { eval $1 } test " value="foo" echo "$value" " But it display nothing. Anyone can help please ?
RevOneX9 (3 rep)
Dec 2, 2022, 01:03 AM • Last activity: Dec 2, 2022, 01:25 AM
0 votes
0 answers
297 views
How does one store the evaluation of a big string with multiple env variables $VAR into another env variable?
Becuase [I need to make sure I run authentication for my nohup commands][1] I need the real command I want to run to be in a string in here: ``` nohup sh -c 'echo $SU_PASSWORD | /afs/cs/software/bin/reauth; python -u $RUN_CMD' > $PWD/nohup.out$SLURM_JOBID & ``` I tried creating the string and storin...
Becuase I need to make sure I run authentication for my nohup commands I need the real command I want to run to be in a string in here:
nohup sh -c 'echo $SU_PASSWORD | /afs/cs/software/bin/reauth; python -u $RUN_CMD' > $PWD/nohup.out$SLURM_JOBID &
I tried creating the string and storing it in the variable $RUN_CMD e.g.
export RUN_CMD='${!HOME}/diversity-for-predictive-success-of-meta-learning/div_src/diversity_src/experiment_mains/main_diversity_with_task2vec.py --manual_loads_name diversity_ala_task2vec_delauny > $OUT_FILE 2> $ERR_FILE'
but I can't make it work. How do I do it? My attempts:
(metalearning_gpu) brando9~ $ export RUN_CMD='${!HOME}/diversity-for-predictive-success-of-meta-learning/div_src/diversity_src/experiment_mains/main_diversity_with_task2vec.py --manual_loads_name diversity_ala_task2vec_delauny > $OUT_FILE 2> $ERR_FILE'
(metalearning_gpu) brando9~ $ echo $RUN_CMD
${!HOME}/diversity-for-predictive-success-of-meta-learning/div_src/diversity_src/experiment_mains/main_diversity_with_task2vec.py --manual_loads_name diversity_ala_task2vec_delauny > $OUT_FILE 2> $ERR_FILE
(metalearning_gpu) brando9~ $ export RUN_CMD=$(echo '$HOME/diversity-for-predictive-success-of-meta-learning/div_src/diversity_src/experiment_mains/main_diversity_with_task2vec.py --manual_loads_name diversity_ala_task2vec_delauny > $OUT_FILE 2> $ERR_FILE')
(metalearning_gpu) brando9~ $ echo $RUN_CMD
$HOME/diversity-for-predictive-success-of-meta-learning/div_src/diversity_src/experiment_mains/main_diversity_with_task2vec.py --manual_loads_name diversity_ala_task2vec_delauny > $OUT_FILE 2> $ERR_FILE
(metalearning_gpu) brando9~ $ export RUN_CMD=$(echo '${!HOME}/diversity-for-predictive-success-of-meta-learning/div_src/diversity_src/experiment_mains/main_diversity_with_task2vec.py --manual_loads_name diversity_ala_task2vec_delauny > $OUT_FILE 2> $ERR_FILE')
(metalearning_gpu) brando9~ $ echo $RUN_CMD
${!HOME}/diversity-for-predictive-success-of-meta-learning/div_src/diversity_src/experiment_mains/main_diversity_with_task2vec.py --manual_loads_name diversity_ala_task2vec_delauny > $OUT_FILE 2> $ERR_FILE
(metalearning_gpu) brando9~ $ export RUN_CMD=(eval '$HOME/diversity-for-predictive-success-of-meta-learning/div_src/diversity_src/experiment_mains/main_diversity_with_task2vec.py --manual_loads_name diversity_ala_task2vec_delauny > $OUT_FILE 2> $ERR_FILE')
(metalearning_gpu) brando9~ $ echo $RUN_CMD
eval
related: - https://stackoverflow.com/questions/14049057/bash-expand-variable-in-a-variable - https://unix.stackexchange.com/questions/341243/bash-perform-variable-expansion-of-string#:~:text=Bash%20uses%20the%20value%20of,is%20known%20as%20indirect%20expansion . - https://unix.stackexchange.com/questions/341243/bash-perform-variable-expansion-of-string/341246?noredirect=1#comment1376474_341246
Charlie Parker (1597 rep)
Nov 23, 2022, 09:13 PM
0 votes
2 answers
438 views
Bash: how to wrap a command to measure its elapsed time?
How to wrap a command to measure its elapsed time? Currently I do it using `eval`: ``` do_cmd_named() { local name=$1 local cmd=$2 echo "$name" local start_time=$(date +%s) eval "$cmd 2>&1" local exit_status=$? local end_time=$(date +%s) local elapsed_time_sec=$((end_time-start_time)) local elapsed_...
How to wrap a command to measure its elapsed time? Currently I do it using eval:
do_cmd_named()
{
  local name=$1
  local cmd=$2

  echo "$name"
  local start_time=$(date +%s)
  eval "$cmd 2>&1"
  local exit_status=$?
  local end_time=$(date +%s)
  local elapsed_time_sec=$((end_time-start_time))
  local elapsed_time_min_sec=$(date -ud "@$elapsed_time_sec" +'%M:%S')
  if [[ $exit_status -ne 0 ]]
  then
    echo "$name failed with exit status $exit_status (elapsed time $elapsed_time_min_sec)"
    return $exit_status
  else
    echo "$name done (elapsed time $elapsed_time_min_sec)"
  fi
}

job()
{
    sleep 1
}

do_cmd_named "do job" "job"
which leads to:
do job
do job done (elapsed time 00:01)
For my cases this approach _almost _ works. However, this approach is considered bad because it violates some rules from BashFAQ . For example, "don't put code inside variables" from [BashFAQ #50](https://mywiki.wooledge.org/BashFAQ/050) (see also [BashFAQ #48](https://mywiki.wooledge.org/BashFAQ/048)). So, the question is: how to do it correctly?
pmor (665 rep)
Nov 21, 2022, 09:22 AM • Last activity: Nov 23, 2022, 04:28 PM
1 votes
1 answers
105 views
Bash - How to make dynamic menu selection without eval
I'm making a script for Docker environments, and I'm a bit stuck with a pigeonhole I've gotten myself into. #!/bin/bash set -euo pipefail # Variables gituser="modem7" gitrepo="docker-devenv" gitfolder="Environments" buildername="DockerDevBuilder" # Colours RED="\e[31m" GREEN="\e[32m" END="\e[0m" ech...
I'm making a script for Docker environments, and I'm a bit stuck with a pigeonhole I've gotten myself into. #!/bin/bash set -euo pipefail # Variables gituser="modem7" gitrepo="docker-devenv" gitfolder="Environments" buildername="DockerDevBuilder" # Colours RED="\e[31m" GREEN="\e[32m" END="\e[0m" echo "=========================================" printf " Checking Dependencies\n" echo "=========================================" printf "Checking if dependencies are installed...\n" pkg_list=(docker jq) tc() { set ${*,,} ; echo ${*^} ; } for pkg in "${pkg_list[@]}" do titlecase=$(tc $pkg) isinstalled=$(dpkg-query -l $pkg > /dev/null 2>&1) if [ $? -eq 0 ]; then printf "~ $titlecase is...${GREEN}installed${END}\n" else printf "~ $titlecase is...${RED}not installed${END}\n" printf "Exiting Script. Install $pkg.\n" echo "=========================================" exit fi done echo "=========================================" cat /dev/null 2>&1; then echo "" echo "Builder $buildername created" else echo "Builder already created, using $buildername" docker buildx use "DockerDevBuilder" echo "" fi echo "Creating $dev_name Environment..." docker buildx build --rm=true --build-arg BUILDKIT_INLINE_CACHE=1 --load -t $lowerdev:dev https://github.com/$gituser/$gitrepo.git#:$gitfolder/$dev_name \ && clear \ && echo "=========================================" \ && echo "Activating $dev_name Dev Environment..." \ && echo "Press CTRL + D or type exit to leave the container" \ && docker run --rm -it --name "$dev_name"Dev"$RANDOM" --hostname "$dev_name"Dev"$RANDOM" "$lowerdev:dev" break ;; "Prune") echo "Clearing Docker cache..." docker system prune -af echo "" echo "Removing Docker buildx builder..." if docker buildx rm "$buildername" > /dev/null 2>&1; then echo "" echo "Builder $buildername removed" else echo "Builder already removed, no action performed" echo "" fi exec bash $0 ;; "Quit") echo "Exiting script" exit ;; *) echo "invalid option $REPLY" ;; esac" done exit 0 I'm currently using "eval "case \"$dev_name\" in" but that seems problematic from what I've read. It works, but I'm not sure if there is a better way to achieve what the results. The choices are created from the folder names in the repo , but I'm not quite sure how to get out of using eval. Am I worrying about something pointless?
Modem7 (11 rep)
Nov 3, 2022, 06:56 PM • Last activity: Nov 4, 2022, 01:17 AM
0 votes
1 answers
1297 views
Using `env` command with `eval`
Suppose I have this in `script.sh`: ```bash env -i SOMEVAR=SOMEVALUE eval -- "$@" ``` I run it with: ```bash ./script.sh echo "\$SOMEVAR" ``` Now it shows: ```bash env: ‘eval’: No such file or directory ``` I suppose it doesn't work because `eval` is a Bash builtin. Any way to make `env` work with `...
Suppose I have this in script.sh:
env -i SOMEVAR=SOMEVALUE eval -- "$@"
I run it with:
./script.sh echo "\$SOMEVAR"
Now it shows:
env: ‘eval’: No such file or directory
I suppose it doesn't work because eval is a Bash builtin. Any way to make env work with eval?
sudoer (65 rep)
Sep 12, 2022, 01:32 PM • Last activity: Sep 12, 2022, 01:53 PM
20 votes
4 answers
66693 views
How can I list all user names and/or home directories?
I want to list all the users’ directories on the machine. Usually, I will do: ls -l /home But I use it in a script that will be deployed on others’ machines and maybe on those machines they don't call it home (e.g. myHome). So I want to generalize it to `ls -l ~`. But it just lists my user’s home di...
I want to list all the users’ directories on the machine. Usually, I will do: ls -l /home But I use it in a script that will be deployed on others’ machines and maybe on those machines they don't call it home (e.g. myHome). So I want to generalize it to ls -l ~. But it just lists my user’s home directory instead of all users’ home directories (basically I want to get a list of the users’ names on the machine). How can I generalize it?
lakerda (355 rep)
Dec 7, 2017, 07:50 AM • Last activity: Sep 5, 2022, 03:13 PM
Showing page 1 of 20 total questions