0

I have got a small snippet (which is part of a script). It makes an array of windows to be displayed by tmux then echo the whole array. This snippet works fine when running in a simple file.sh.

mtmux() {                                                                                                                                                                                     
    
   #tmux kill-server &>/dev/null 
   #[[ $(ps -ef | grep 'tmux attach-sess' | grep -v grep) ]] && kill -9 $(ps -ef | grep 'attach-sess' | grep -v grep | awk '{ print $2 }') &>/dev/null
   #[[ $(pgrep tmux) ]] && pkill tmux &>/dev/null
   pkill tmux >/dev/null  
                                                                                                                                                                                          
   #I input the name of each window that tmux should display; when pressing 't', the loop stops                                                                                              
  WINDOWS=()                                                                                                                                                                                
  IFS=$'\n'                                                                                                                                                                                 
  while [ "${TITLE}" != 't' ]                                                                                                                                                               
  do                                                                                                                                                                                        
     read -p 'Add a new window?' TITLE                                                                                                                                                     
     WINDOWS+=("${TITLE}")                                                                                                                                                                 
  done                                                                                                                                                                                      
                                                                                                                                                                                          
  #I remove the last element from the created array (cos it's just the 't' I passed to escape the loop).                                                                                  
  unset WINDOWS[-1]                                                                                                                                                                      
  echo "${WINDOWS[@]}"
}

mtmux

As soon as I put it in my .bashrc, the unset command spawns the following error:

    bash: unset: [-1]: bad array subscript

Issuing 'source ~/.bashrc' gives no error. Why such an error?

thanx folks!!

achille
  • 173
  • 1
  • 3
  • 12
  • I see two reasons it might give that error: 1) the array's empty a that point, so there's no last element to unset, or 2) it's running under an older version of bash that doesn't support negative array indexes. Anyway, I'd rewrite that loop so it never adds the irrelevant entry in the first place. Also... are you actually running the `mtmux` function -- which appears to require interactive input -- in .bashrc? That seems like a really bad idea. – Gordon Davisson Jul 17 '23 at 17:10
  • 1) I fill the array the same way in both cases (3 or 4 windows). 2) Are you meaning there is a security issue? – achille Jul 17 '23 at 17:17
  • What version of `bash` are you using? Support for negative array subscripts was added in `bash` 4.3, I believe. – chepner Jul 17 '23 at 17:30
  • I installed a brand new Debian this morning with GNU bash, version 5.1.4(1)-release (x86_64-pc-linux-gnu) – achille Jul 17 '23 at 17:31
  • I don't mean there's a security problem, I mean that the setup might get run at times where it's not appropriate. It'd make more sense to have something like that in .bash_profile, but even there it'd cause trouble with e.g. remote access with `scp` and `rsync` because those tools don't know how to go through the interactive prompts. BTW, changing `IFS` (and not immediately changing it back) can also cause trouble. – Gordon Davisson Jul 17 '23 at 17:52
  • it's very strange because I have got another function which never failed before and now I have got the same issue: When in bashrc, it always fails. – achille Jul 17 '23 at 18:38
  • 1
    I can gen the same error by running `mtmux()` twice in a row .... 1st time I exit the loop by providing `TITLE=t` ... 2nd time `TITLE` is still set to `t` so the loop is bypassed and the `unset` is applied against an empty `WINDOWS[]` array; any chance that somewhere earlier in your `.bashrc` or `.profile` you manage to set `TITLE=t`? or perhaps call `mtmux()` a 2nd time without first unsetting `TITLE`? one quick/easy test would be to add `unset TITLE` just before the `while` loop ; alternatively, add `typeset -p TITLE` just before the `while` loop to see if it is in fact already set to `t` – markp-fuso Jul 17 '23 at 18:46
  • another option would be to test the number of elements in the array and only unset if the count > 0 (eg, `[[ "${#WINDOWS[@]}" -gt 0 ]] && unset WINDOWS[-1]`); 'course, if the array is empty you may want to print a warning/message (eg, `[[ "${#WINDOWS[@]}" -gt 0 ]] && unset WINDOWS[-1] || echo "array is empty"`) – markp-fuso Jul 17 '23 at 18:48
  • while (probably) not an issue in this case ... get used to *not* using ALLCAP variable names since system/env variables are typically ALLCAP; sooner or later you're likely to get some funky behavior when you inadvertently redefine a system variable (eg, `PWD`, `PATH`) – markp-fuso Jul 17 '23 at 18:55
  • 1
    *`I have got another function which never failed before and now I have got the same issue:`* --- this sounds like you may be re-using a common (global) variable across functions and test/conditions (eg, `[ "${TITLE}" != 't' ]`); if this is the case then consider using different variable names, clearing/unsetting the variable at the beginning of each function, or defining the variable as local in each function (eg, `local TITLE` – markp-fuso Jul 17 '23 at 19:00
  • Far easier just to rename the window once tmux is up and running [How do I rename a pane in tmux?](https://stackoverflow.com/q/40234553/3422102) and you can also script tmux startup itself. Both better options than trying to make bashrc interactive... See also [How do I set tmux to open specified windows at startup?](https://stackoverflow.com/q/5609192/3422102) – David C. Rankin Jul 17 '23 at 22:07

0 Answers0