Can I introspect the type of a bash variable?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
2
down vote

favorite












I'm writing a function that outputs dates. I'd like to allow the user to customize the output by supplying arguments to date with an environment variable. To preserve white space in format strings, I'd like to accept args in an array like this:



function argdates 
while [ $# -gt 0 ] && date "$DATE_ARGS[@]" -d @$1
do shift
done



The user might want to use an array if they have spaces in a date format string:



DATE_ARGS=( -u "+%y/%U, %I%p %a" )
argdates 1476395008 1493172224

# output:
# 16/41, 09PM Thu
# 17/17, 02AM Wed


But in this case, an array might be overkill:



DATE_ARGS="-u -Iseconds"
argdates 1476395008 1493172224

# output:
# date: invalid option -- ' '
# Try 'date --help' for more information.

# output should be:
# 2016-10-13T21:43:28+00:00
# 2017-04-26T02:03:44+00:00


I don't want to require an array for simple cases like this. Is it possible to tell what type the variable is?










share|improve this question





















  • related unix.stackexchange.com/q/246026/38906
    – cuonglm
    Apr 13 '17 at 4:25










  • In the second case, what's so hard about writing DATE_ARGS=(-u -Iseconds)?
    – Barmar
    Apr 13 '17 at 6:22










  • You can't export an array as an environment variable. See stackoverflow.com/questions/5564418/…
    – Barmar
    Apr 13 '17 at 6:25










  • @Barmar yes that's basically where I'm at right now: Assume end user is comfortable creating a bash array. But the common way to export arguments for a script to use is the second example, not with an array.
    – Travis Wellman
    Apr 13 '17 at 6:26














up vote
2
down vote

favorite












I'm writing a function that outputs dates. I'd like to allow the user to customize the output by supplying arguments to date with an environment variable. To preserve white space in format strings, I'd like to accept args in an array like this:



function argdates 
while [ $# -gt 0 ] && date "$DATE_ARGS[@]" -d @$1
do shift
done



The user might want to use an array if they have spaces in a date format string:



DATE_ARGS=( -u "+%y/%U, %I%p %a" )
argdates 1476395008 1493172224

# output:
# 16/41, 09PM Thu
# 17/17, 02AM Wed


But in this case, an array might be overkill:



DATE_ARGS="-u -Iseconds"
argdates 1476395008 1493172224

# output:
# date: invalid option -- ' '
# Try 'date --help' for more information.

# output should be:
# 2016-10-13T21:43:28+00:00
# 2017-04-26T02:03:44+00:00


I don't want to require an array for simple cases like this. Is it possible to tell what type the variable is?










share|improve this question





















  • related unix.stackexchange.com/q/246026/38906
    – cuonglm
    Apr 13 '17 at 4:25










  • In the second case, what's so hard about writing DATE_ARGS=(-u -Iseconds)?
    – Barmar
    Apr 13 '17 at 6:22










  • You can't export an array as an environment variable. See stackoverflow.com/questions/5564418/…
    – Barmar
    Apr 13 '17 at 6:25










  • @Barmar yes that's basically where I'm at right now: Assume end user is comfortable creating a bash array. But the common way to export arguments for a script to use is the second example, not with an array.
    – Travis Wellman
    Apr 13 '17 at 6:26












up vote
2
down vote

favorite









up vote
2
down vote

favorite











I'm writing a function that outputs dates. I'd like to allow the user to customize the output by supplying arguments to date with an environment variable. To preserve white space in format strings, I'd like to accept args in an array like this:



function argdates 
while [ $# -gt 0 ] && date "$DATE_ARGS[@]" -d @$1
do shift
done



The user might want to use an array if they have spaces in a date format string:



DATE_ARGS=( -u "+%y/%U, %I%p %a" )
argdates 1476395008 1493172224

# output:
# 16/41, 09PM Thu
# 17/17, 02AM Wed


But in this case, an array might be overkill:



DATE_ARGS="-u -Iseconds"
argdates 1476395008 1493172224

# output:
# date: invalid option -- ' '
# Try 'date --help' for more information.

# output should be:
# 2016-10-13T21:43:28+00:00
# 2017-04-26T02:03:44+00:00


I don't want to require an array for simple cases like this. Is it possible to tell what type the variable is?










share|improve this question













I'm writing a function that outputs dates. I'd like to allow the user to customize the output by supplying arguments to date with an environment variable. To preserve white space in format strings, I'd like to accept args in an array like this:



function argdates 
while [ $# -gt 0 ] && date "$DATE_ARGS[@]" -d @$1
do shift
done



The user might want to use an array if they have spaces in a date format string:



DATE_ARGS=( -u "+%y/%U, %I%p %a" )
argdates 1476395008 1493172224

# output:
# 16/41, 09PM Thu
# 17/17, 02AM Wed


But in this case, an array might be overkill:



DATE_ARGS="-u -Iseconds"
argdates 1476395008 1493172224

# output:
# date: invalid option -- ' '
# Try 'date --help' for more information.

# output should be:
# 2016-10-13T21:43:28+00:00
# 2017-04-26T02:03:44+00:00


I don't want to require an array for simple cases like this. Is it possible to tell what type the variable is?







bash environment-variables variable array arguments






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Apr 13 '17 at 3:18









Travis Wellman

12817




12817











  • related unix.stackexchange.com/q/246026/38906
    – cuonglm
    Apr 13 '17 at 4:25










  • In the second case, what's so hard about writing DATE_ARGS=(-u -Iseconds)?
    – Barmar
    Apr 13 '17 at 6:22










  • You can't export an array as an environment variable. See stackoverflow.com/questions/5564418/…
    – Barmar
    Apr 13 '17 at 6:25










  • @Barmar yes that's basically where I'm at right now: Assume end user is comfortable creating a bash array. But the common way to export arguments for a script to use is the second example, not with an array.
    – Travis Wellman
    Apr 13 '17 at 6:26
















  • related unix.stackexchange.com/q/246026/38906
    – cuonglm
    Apr 13 '17 at 4:25










  • In the second case, what's so hard about writing DATE_ARGS=(-u -Iseconds)?
    – Barmar
    Apr 13 '17 at 6:22










  • You can't export an array as an environment variable. See stackoverflow.com/questions/5564418/…
    – Barmar
    Apr 13 '17 at 6:25










  • @Barmar yes that's basically where I'm at right now: Assume end user is comfortable creating a bash array. But the common way to export arguments for a script to use is the second example, not with an array.
    – Travis Wellman
    Apr 13 '17 at 6:26















related unix.stackexchange.com/q/246026/38906
– cuonglm
Apr 13 '17 at 4:25




related unix.stackexchange.com/q/246026/38906
– cuonglm
Apr 13 '17 at 4:25












In the second case, what's so hard about writing DATE_ARGS=(-u -Iseconds)?
– Barmar
Apr 13 '17 at 6:22




In the second case, what's so hard about writing DATE_ARGS=(-u -Iseconds)?
– Barmar
Apr 13 '17 at 6:22












You can't export an array as an environment variable. See stackoverflow.com/questions/5564418/…
– Barmar
Apr 13 '17 at 6:25




You can't export an array as an environment variable. See stackoverflow.com/questions/5564418/…
– Barmar
Apr 13 '17 at 6:25












@Barmar yes that's basically where I'm at right now: Assume end user is comfortable creating a bash array. But the common way to export arguments for a script to use is the second example, not with an array.
– Travis Wellman
Apr 13 '17 at 6:26




@Barmar yes that's basically where I'm at right now: Assume end user is comfortable creating a bash array. But the common way to export arguments for a script to use is the second example, not with an array.
– Travis Wellman
Apr 13 '17 at 6:26










2 Answers
2






active

oldest

votes

















up vote
0
down vote













It seems to me that you may want to let your function pass on any command line options directly to GNU date while treating numerical non-option specially:



argdates () date "$opts[@]" -f -



This bash function would go through its command line arguments and save them in the opts array, until it hits an argument which is -- (the standard way of signalling the end of options) or that starts with a digit. Each argument saved into opts is shifted off of the list of command line arguments.



Once an argument has been found that is not an option to date, we assume that the rest of the arguments are UNIX epoch timestamps and loop over these, calling date with our saved options for each timestamp. See the comment in the code for how to do this looping more efficiently.



Example invocations:



$ argdates 1476395008 1493172224
Thu Oct 13 23:43:28 CEST 2016
Wed Apr 26 04:03:44 CEST 2017




$ argdates -- 1476395008 1493172224
Thu Oct 13 23:43:28 CEST 2016
Wed Apr 26 04:03:44 CEST 2017




$ argdates +%D 1476395008 1493172224
10/13/16
04/26/17




$ argdates +%F 1476395008 1493172224
2016-10-13
2017-04-26




$ argdates -u 1476395008 1493172224
Thu Oct 13 21:43:28 UTC 2016
Wed Apr 26 02:03:44 UTC 2017




$ argdates -u -Iseconds 1476395008 1493172224
2016-10-13T21:43:28+00:00
2017-04-26T02:03:44+00:00





share|improve this answer





























    up vote
    0
    down vote













    You could do that much easier by giving up on using arrays and letting the user specify DATE_ARGS simply as a string that should be inserted in the command line of date:



    $ argdates()
    for d; do printf %s "$DATE_ARGS"
    $ DATE_ARGS='-u "+%y/%U, %I%p %a"' argdates 1476395008 1493172224
    16/41, 09PM Thu
    17/17, 02AM Wed
    $ DATE_ARGS='-u -Iseconds' argdates 1476395008 1493172224
    2016-10-13T21:43:28+00:00
    2017-04-26T02:03:44+00:00





    share|improve this answer






















      Your Answer








      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "106"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f358695%2fcan-i-introspect-the-type-of-a-bash-variable%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      0
      down vote













      It seems to me that you may want to let your function pass on any command line options directly to GNU date while treating numerical non-option specially:



      argdates () date "$opts[@]" -f -



      This bash function would go through its command line arguments and save them in the opts array, until it hits an argument which is -- (the standard way of signalling the end of options) or that starts with a digit. Each argument saved into opts is shifted off of the list of command line arguments.



      Once an argument has been found that is not an option to date, we assume that the rest of the arguments are UNIX epoch timestamps and loop over these, calling date with our saved options for each timestamp. See the comment in the code for how to do this looping more efficiently.



      Example invocations:



      $ argdates 1476395008 1493172224
      Thu Oct 13 23:43:28 CEST 2016
      Wed Apr 26 04:03:44 CEST 2017




      $ argdates -- 1476395008 1493172224
      Thu Oct 13 23:43:28 CEST 2016
      Wed Apr 26 04:03:44 CEST 2017




      $ argdates +%D 1476395008 1493172224
      10/13/16
      04/26/17




      $ argdates +%F 1476395008 1493172224
      2016-10-13
      2017-04-26




      $ argdates -u 1476395008 1493172224
      Thu Oct 13 21:43:28 UTC 2016
      Wed Apr 26 02:03:44 UTC 2017




      $ argdates -u -Iseconds 1476395008 1493172224
      2016-10-13T21:43:28+00:00
      2017-04-26T02:03:44+00:00





      share|improve this answer


























        up vote
        0
        down vote













        It seems to me that you may want to let your function pass on any command line options directly to GNU date while treating numerical non-option specially:



        argdates () date "$opts[@]" -f -



        This bash function would go through its command line arguments and save them in the opts array, until it hits an argument which is -- (the standard way of signalling the end of options) or that starts with a digit. Each argument saved into opts is shifted off of the list of command line arguments.



        Once an argument has been found that is not an option to date, we assume that the rest of the arguments are UNIX epoch timestamps and loop over these, calling date with our saved options for each timestamp. See the comment in the code for how to do this looping more efficiently.



        Example invocations:



        $ argdates 1476395008 1493172224
        Thu Oct 13 23:43:28 CEST 2016
        Wed Apr 26 04:03:44 CEST 2017




        $ argdates -- 1476395008 1493172224
        Thu Oct 13 23:43:28 CEST 2016
        Wed Apr 26 04:03:44 CEST 2017




        $ argdates +%D 1476395008 1493172224
        10/13/16
        04/26/17




        $ argdates +%F 1476395008 1493172224
        2016-10-13
        2017-04-26




        $ argdates -u 1476395008 1493172224
        Thu Oct 13 21:43:28 UTC 2016
        Wed Apr 26 02:03:44 UTC 2017




        $ argdates -u -Iseconds 1476395008 1493172224
        2016-10-13T21:43:28+00:00
        2017-04-26T02:03:44+00:00





        share|improve this answer
























          up vote
          0
          down vote










          up vote
          0
          down vote









          It seems to me that you may want to let your function pass on any command line options directly to GNU date while treating numerical non-option specially:



          argdates () date "$opts[@]" -f -



          This bash function would go through its command line arguments and save them in the opts array, until it hits an argument which is -- (the standard way of signalling the end of options) or that starts with a digit. Each argument saved into opts is shifted off of the list of command line arguments.



          Once an argument has been found that is not an option to date, we assume that the rest of the arguments are UNIX epoch timestamps and loop over these, calling date with our saved options for each timestamp. See the comment in the code for how to do this looping more efficiently.



          Example invocations:



          $ argdates 1476395008 1493172224
          Thu Oct 13 23:43:28 CEST 2016
          Wed Apr 26 04:03:44 CEST 2017




          $ argdates -- 1476395008 1493172224
          Thu Oct 13 23:43:28 CEST 2016
          Wed Apr 26 04:03:44 CEST 2017




          $ argdates +%D 1476395008 1493172224
          10/13/16
          04/26/17




          $ argdates +%F 1476395008 1493172224
          2016-10-13
          2017-04-26




          $ argdates -u 1476395008 1493172224
          Thu Oct 13 21:43:28 UTC 2016
          Wed Apr 26 02:03:44 UTC 2017




          $ argdates -u -Iseconds 1476395008 1493172224
          2016-10-13T21:43:28+00:00
          2017-04-26T02:03:44+00:00





          share|improve this answer














          It seems to me that you may want to let your function pass on any command line options directly to GNU date while treating numerical non-option specially:



          argdates () date "$opts[@]" -f -



          This bash function would go through its command line arguments and save them in the opts array, until it hits an argument which is -- (the standard way of signalling the end of options) or that starts with a digit. Each argument saved into opts is shifted off of the list of command line arguments.



          Once an argument has been found that is not an option to date, we assume that the rest of the arguments are UNIX epoch timestamps and loop over these, calling date with our saved options for each timestamp. See the comment in the code for how to do this looping more efficiently.



          Example invocations:



          $ argdates 1476395008 1493172224
          Thu Oct 13 23:43:28 CEST 2016
          Wed Apr 26 04:03:44 CEST 2017




          $ argdates -- 1476395008 1493172224
          Thu Oct 13 23:43:28 CEST 2016
          Wed Apr 26 04:03:44 CEST 2017




          $ argdates +%D 1476395008 1493172224
          10/13/16
          04/26/17




          $ argdates +%F 1476395008 1493172224
          2016-10-13
          2017-04-26




          $ argdates -u 1476395008 1493172224
          Thu Oct 13 21:43:28 UTC 2016
          Wed Apr 26 02:03:44 UTC 2017




          $ argdates -u -Iseconds 1476395008 1493172224
          2016-10-13T21:43:28+00:00
          2017-04-26T02:03:44+00:00






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 25 at 11:43

























          answered Nov 25 at 11:38









          Kusalananda

          118k16223361




          118k16223361






















              up vote
              0
              down vote













              You could do that much easier by giving up on using arrays and letting the user specify DATE_ARGS simply as a string that should be inserted in the command line of date:



              $ argdates()
              for d; do printf %s "$DATE_ARGS"
              $ DATE_ARGS='-u "+%y/%U, %I%p %a"' argdates 1476395008 1493172224
              16/41, 09PM Thu
              17/17, 02AM Wed
              $ DATE_ARGS='-u -Iseconds' argdates 1476395008 1493172224
              2016-10-13T21:43:28+00:00
              2017-04-26T02:03:44+00:00





              share|improve this answer


























                up vote
                0
                down vote













                You could do that much easier by giving up on using arrays and letting the user specify DATE_ARGS simply as a string that should be inserted in the command line of date:



                $ argdates()
                for d; do printf %s "$DATE_ARGS"
                $ DATE_ARGS='-u "+%y/%U, %I%p %a"' argdates 1476395008 1493172224
                16/41, 09PM Thu
                17/17, 02AM Wed
                $ DATE_ARGS='-u -Iseconds' argdates 1476395008 1493172224
                2016-10-13T21:43:28+00:00
                2017-04-26T02:03:44+00:00





                share|improve this answer
























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  You could do that much easier by giving up on using arrays and letting the user specify DATE_ARGS simply as a string that should be inserted in the command line of date:



                  $ argdates()
                  for d; do printf %s "$DATE_ARGS"
                  $ DATE_ARGS='-u "+%y/%U, %I%p %a"' argdates 1476395008 1493172224
                  16/41, 09PM Thu
                  17/17, 02AM Wed
                  $ DATE_ARGS='-u -Iseconds' argdates 1476395008 1493172224
                  2016-10-13T21:43:28+00:00
                  2017-04-26T02:03:44+00:00





                  share|improve this answer














                  You could do that much easier by giving up on using arrays and letting the user specify DATE_ARGS simply as a string that should be inserted in the command line of date:



                  $ argdates()
                  for d; do printf %s "$DATE_ARGS"
                  $ DATE_ARGS='-u "+%y/%U, %I%p %a"' argdates 1476395008 1493172224
                  16/41, 09PM Thu
                  17/17, 02AM Wed
                  $ DATE_ARGS='-u -Iseconds' argdates 1476395008 1493172224
                  2016-10-13T21:43:28+00:00
                  2017-04-26T02:03:44+00:00






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 25 at 14:40

























                  answered Nov 25 at 14:33









                  pizdelect

                  16114




                  16114



























                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Unix & Linux Stack Exchange!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f358695%2fcan-i-introspect-the-type-of-a-bash-variable%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown






                      Popular posts from this blog

                      How to check contact read email or not when send email to Individual?

                      Displaying single band from multi-band raster using QGIS

                      How many registers does an x86_64 CPU actually have?