Uploaded image for project: 'RHEL'
  1. RHEL
  2. RHEL-45363

Inconsistency with "source", $LINENO and $BASH_LINENO

    • Icon: Bug Bug
    • Resolution: Not a Bug
    • Icon: Minor Minor
    • None
    • rhel-8.9.0, rhel-9.6
    • bash
    • None
    • None
    • Low
    • rhel-sst-cs-plumbers
    • ssg_core_services
    • 5
    • False
    • Hide

      None

      Show
      None
    • None
    • None
    • None
    • None
    • All
    • None

      Using the sample script:

      $ cat source_vs_script.sh
      #!/bin/bash
      grab_line(){
      
      	echo "${FUNCNAME[1]} -- ${BASH_LINENO[0]}"
      }
      test() (
      
      	grab_line
      
      )
      test2() (
      
      	echo "$LINENO"
      )
      
      test
      test2
      

      Will show different results with source and simple execution:

      bash-5.2$ source source_vs_script.sh
      test -- 9
      14
      bash-5.2$ source source_vs_script.sh
      test -- 9
      14
      bash-5.2$ test
      test -- 8
      bash-5.2$ test2
      13
      

      Note that when source is used, the line numbers are "one less".

      and with bash-4.4

      bash-4.4$ source source_vs_script.sh
      test -- 9
      14
      bash-4.4$ source source_vs_script.sh
      test -- 9
      14
      bash-5.2$ test
      test -- 7
      bash-4.4$ test2
      12
      

      Note that when source is used, the line numbers are "two less".

      Initially I did not fully understand the issue, and did adapt execute_cmd.h, execute_cmd.c, copy_cmd.c and make_cmd.c, based on https://git.savannah.gnu.org/cgit/bash.git/diff/execute_cmd.c?id=74091dd4e8086db518b30df7f222691524469998
      just did not add the changes to enforce counting line numbers indexed from one, and not zero. But it did not make any effect; basically added a line field to struct subshell and added/used the GET_LINE_NUMBER and SET_LINE_NMUBER macros.

      The difference on indexing from one and not zero should be the reason of in bash-5.2 showing the line with extra one.

      If removing the first line

      #!/bin/bash 

      it will show the "expected" result when source'ing and calling the test and test2 functions from the shell.

      The first guess of the discrepancy could be related to this chunk in parse.y:

      void
      push_stream (reset_lineno)
           int reset_lineno;
      {
        STREAM_SAVER *saver = (STREAM_SAVER *)xmalloc (sizeof (STREAM_SAVER));
      
        xbcopy ((char *)&bash_input, (char *)&(saver->bash_input), sizeof (BASH_INPUT));
      
      #if defined (BUFFERED_INPUT)
        saver->bstream = (BUFFERED_STREAM *)NULL;
        /* If we have a buffered stream, clear out buffers[fd]. */
        if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
          saver->bstream = set_buffered_stream (bash_input.location.buffered_fd,
                                                (BUFFERED_STREAM *)NULL);
      #endif /* BUFFERED_INPUT */
      
        saver->line = line_number;
        bash_input.name = (char *)NULL;
        saver->next = stream_list;
        stream_list = saver;
        EOF_Reached = 0;
        if (reset_lineno)
          line_number = 0;
      }
      

      Note the setting of line_number to zero.

      The conclusion is that there are two problems:

      • The #!/path/to/interpreter first line is not accounted when using source.
        This problem happens in bash-4.4 and bash-5.2 at least.
      • Bash-4.4 starts counting at 0, not 1 when source is used.

              rhn-support-svashish Siteshwar Vashisht
              rhn-support-pandrade Paulo Andrade
              Siteshwar Vashisht Siteshwar Vashisht
              Karel Volný Karel Volný
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Created:
                Updated:
                Resolved: