S3 Bash Tools Part 3

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





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
2
down vote

favorite












This is a follow on to a previous question:



Part 3: User Scripts



All the code I am submitting here is available in github




The reason to write these tools is so I can prototype and quickly verify that I am doing things correctly before implementing them in C++. This is mainly necessary because the documentation these scripts are based on are relatively bad and confusing.




The scripts used by users:



s3cp



#!/usr/bin/env bash

badflag=0
declare -a ARGS

function usage
echo "Usage:"
echo "s3cp <file> <s3-url> [--key=<key>] [--secret=<secret>] [--verbose] [--dryrun]"
echo "s3cp <s3-url> <file> [--key=<key>] [--secret=<secret>] [--verbose] [--dryrun]"
echo
echo "s3-url: s3://<bucket>/<Object-Path>"
exit 1


verbose=''
dryrun=0
access=$AMZ_ACCESS_KEY
secret=$AMZ_SECRET_KEY
for var in "$@"; do
if [[ "$var" == '--verbose' ]]; then
verbose='/dev/stdout'
continue
fi
if [[ "$var" == '--dryrun' ]]; then
dryrun=1
continue;
fi
if [[ "$var%=*" == "--key" ]]; then
access=$var#*=
continue;
fi
if [[ "$var%=*" == "--secret" ]]; then
secret=$var#*=
continue;
fi
flag=$var#-
if [[ "$flag" != $var ]]; then
badflag=1
echo "Bad flag: $var"
continue
fi
ARGS+=("$var")
done

if [[ "$access" == "" || "$secret" == "" ]]; then
echo "Error: No Access or Secret provided."
echo "These can be set in the environment variables AMZ_ACCESS_KEY/AMZ_SECRET_KEY or passed with flags"
usage
fi

if [[ $#ARGS[@] != 2 || $badflag != 0 ]]; then
usage
fi

src=$ARGS[0]
dst=$ARGS[1]

doUpload=0
doDownload=0
srcS3=$src#s3://
if [[ "$src" == "$srcS3" ]]; then
doUpload=1
fi
dstS3=$dst#s3://
if [[ "$dst" == "$dstS3" ]]; then
doDownload=1
fi

if [[ $doUpload == 0 && $doDownload == 0 ]]; then
echo "Neither source or destination is on S3. Just use normal cp"
usage
fi
if [[ $doUpload == 1 && $doDownload == 1 ]]; then
echo "Both source or destination is on S3. Don't support move yet."
usage
fi

dir="$(cd "$(dirname "$BASH_SOURCE[0]")" && pwd)"
source $dir/s3/signature


if [[ $doUpload == 1 ]]; then
source $dir/s3/upload
upload "$src" "$dst" "$access" "$secret" '' "$verbose" "$dryrun"
else
source $dir/s3/download
download "$src" "$dst" "$access" "$secret" '' "$verbose" "$dryrun"
fi






share|improve this question

























    up vote
    2
    down vote

    favorite












    This is a follow on to a previous question:



    Part 3: User Scripts



    All the code I am submitting here is available in github




    The reason to write these tools is so I can prototype and quickly verify that I am doing things correctly before implementing them in C++. This is mainly necessary because the documentation these scripts are based on are relatively bad and confusing.




    The scripts used by users:



    s3cp



    #!/usr/bin/env bash

    badflag=0
    declare -a ARGS

    function usage
    echo "Usage:"
    echo "s3cp <file> <s3-url> [--key=<key>] [--secret=<secret>] [--verbose] [--dryrun]"
    echo "s3cp <s3-url> <file> [--key=<key>] [--secret=<secret>] [--verbose] [--dryrun]"
    echo
    echo "s3-url: s3://<bucket>/<Object-Path>"
    exit 1


    verbose=''
    dryrun=0
    access=$AMZ_ACCESS_KEY
    secret=$AMZ_SECRET_KEY
    for var in "$@"; do
    if [[ "$var" == '--verbose' ]]; then
    verbose='/dev/stdout'
    continue
    fi
    if [[ "$var" == '--dryrun' ]]; then
    dryrun=1
    continue;
    fi
    if [[ "$var%=*" == "--key" ]]; then
    access=$var#*=
    continue;
    fi
    if [[ "$var%=*" == "--secret" ]]; then
    secret=$var#*=
    continue;
    fi
    flag=$var#-
    if [[ "$flag" != $var ]]; then
    badflag=1
    echo "Bad flag: $var"
    continue
    fi
    ARGS+=("$var")
    done

    if [[ "$access" == "" || "$secret" == "" ]]; then
    echo "Error: No Access or Secret provided."
    echo "These can be set in the environment variables AMZ_ACCESS_KEY/AMZ_SECRET_KEY or passed with flags"
    usage
    fi

    if [[ $#ARGS[@] != 2 || $badflag != 0 ]]; then
    usage
    fi

    src=$ARGS[0]
    dst=$ARGS[1]

    doUpload=0
    doDownload=0
    srcS3=$src#s3://
    if [[ "$src" == "$srcS3" ]]; then
    doUpload=1
    fi
    dstS3=$dst#s3://
    if [[ "$dst" == "$dstS3" ]]; then
    doDownload=1
    fi

    if [[ $doUpload == 0 && $doDownload == 0 ]]; then
    echo "Neither source or destination is on S3. Just use normal cp"
    usage
    fi
    if [[ $doUpload == 1 && $doDownload == 1 ]]; then
    echo "Both source or destination is on S3. Don't support move yet."
    usage
    fi

    dir="$(cd "$(dirname "$BASH_SOURCE[0]")" && pwd)"
    source $dir/s3/signature


    if [[ $doUpload == 1 ]]; then
    source $dir/s3/upload
    upload "$src" "$dst" "$access" "$secret" '' "$verbose" "$dryrun"
    else
    source $dir/s3/download
    download "$src" "$dst" "$access" "$secret" '' "$verbose" "$dryrun"
    fi






    share|improve this question





















      up vote
      2
      down vote

      favorite









      up vote
      2
      down vote

      favorite











      This is a follow on to a previous question:



      Part 3: User Scripts



      All the code I am submitting here is available in github




      The reason to write these tools is so I can prototype and quickly verify that I am doing things correctly before implementing them in C++. This is mainly necessary because the documentation these scripts are based on are relatively bad and confusing.




      The scripts used by users:



      s3cp



      #!/usr/bin/env bash

      badflag=0
      declare -a ARGS

      function usage
      echo "Usage:"
      echo "s3cp <file> <s3-url> [--key=<key>] [--secret=<secret>] [--verbose] [--dryrun]"
      echo "s3cp <s3-url> <file> [--key=<key>] [--secret=<secret>] [--verbose] [--dryrun]"
      echo
      echo "s3-url: s3://<bucket>/<Object-Path>"
      exit 1


      verbose=''
      dryrun=0
      access=$AMZ_ACCESS_KEY
      secret=$AMZ_SECRET_KEY
      for var in "$@"; do
      if [[ "$var" == '--verbose' ]]; then
      verbose='/dev/stdout'
      continue
      fi
      if [[ "$var" == '--dryrun' ]]; then
      dryrun=1
      continue;
      fi
      if [[ "$var%=*" == "--key" ]]; then
      access=$var#*=
      continue;
      fi
      if [[ "$var%=*" == "--secret" ]]; then
      secret=$var#*=
      continue;
      fi
      flag=$var#-
      if [[ "$flag" != $var ]]; then
      badflag=1
      echo "Bad flag: $var"
      continue
      fi
      ARGS+=("$var")
      done

      if [[ "$access" == "" || "$secret" == "" ]]; then
      echo "Error: No Access or Secret provided."
      echo "These can be set in the environment variables AMZ_ACCESS_KEY/AMZ_SECRET_KEY or passed with flags"
      usage
      fi

      if [[ $#ARGS[@] != 2 || $badflag != 0 ]]; then
      usage
      fi

      src=$ARGS[0]
      dst=$ARGS[1]

      doUpload=0
      doDownload=0
      srcS3=$src#s3://
      if [[ "$src" == "$srcS3" ]]; then
      doUpload=1
      fi
      dstS3=$dst#s3://
      if [[ "$dst" == "$dstS3" ]]; then
      doDownload=1
      fi

      if [[ $doUpload == 0 && $doDownload == 0 ]]; then
      echo "Neither source or destination is on S3. Just use normal cp"
      usage
      fi
      if [[ $doUpload == 1 && $doDownload == 1 ]]; then
      echo "Both source or destination is on S3. Don't support move yet."
      usage
      fi

      dir="$(cd "$(dirname "$BASH_SOURCE[0]")" && pwd)"
      source $dir/s3/signature


      if [[ $doUpload == 1 ]]; then
      source $dir/s3/upload
      upload "$src" "$dst" "$access" "$secret" '' "$verbose" "$dryrun"
      else
      source $dir/s3/download
      download "$src" "$dst" "$access" "$secret" '' "$verbose" "$dryrun"
      fi






      share|improve this question











      This is a follow on to a previous question:



      Part 3: User Scripts



      All the code I am submitting here is available in github




      The reason to write these tools is so I can prototype and quickly verify that I am doing things correctly before implementing them in C++. This is mainly necessary because the documentation these scripts are based on are relatively bad and confusing.




      The scripts used by users:



      s3cp



      #!/usr/bin/env bash

      badflag=0
      declare -a ARGS

      function usage
      echo "Usage:"
      echo "s3cp <file> <s3-url> [--key=<key>] [--secret=<secret>] [--verbose] [--dryrun]"
      echo "s3cp <s3-url> <file> [--key=<key>] [--secret=<secret>] [--verbose] [--dryrun]"
      echo
      echo "s3-url: s3://<bucket>/<Object-Path>"
      exit 1


      verbose=''
      dryrun=0
      access=$AMZ_ACCESS_KEY
      secret=$AMZ_SECRET_KEY
      for var in "$@"; do
      if [[ "$var" == '--verbose' ]]; then
      verbose='/dev/stdout'
      continue
      fi
      if [[ "$var" == '--dryrun' ]]; then
      dryrun=1
      continue;
      fi
      if [[ "$var%=*" == "--key" ]]; then
      access=$var#*=
      continue;
      fi
      if [[ "$var%=*" == "--secret" ]]; then
      secret=$var#*=
      continue;
      fi
      flag=$var#-
      if [[ "$flag" != $var ]]; then
      badflag=1
      echo "Bad flag: $var"
      continue
      fi
      ARGS+=("$var")
      done

      if [[ "$access" == "" || "$secret" == "" ]]; then
      echo "Error: No Access or Secret provided."
      echo "These can be set in the environment variables AMZ_ACCESS_KEY/AMZ_SECRET_KEY or passed with flags"
      usage
      fi

      if [[ $#ARGS[@] != 2 || $badflag != 0 ]]; then
      usage
      fi

      src=$ARGS[0]
      dst=$ARGS[1]

      doUpload=0
      doDownload=0
      srcS3=$src#s3://
      if [[ "$src" == "$srcS3" ]]; then
      doUpload=1
      fi
      dstS3=$dst#s3://
      if [[ "$dst" == "$dstS3" ]]; then
      doDownload=1
      fi

      if [[ $doUpload == 0 && $doDownload == 0 ]]; then
      echo "Neither source or destination is on S3. Just use normal cp"
      usage
      fi
      if [[ $doUpload == 1 && $doDownload == 1 ]]; then
      echo "Both source or destination is on S3. Don't support move yet."
      usage
      fi

      dir="$(cd "$(dirname "$BASH_SOURCE[0]")" && pwd)"
      source $dir/s3/signature


      if [[ $doUpload == 1 ]]; then
      source $dir/s3/upload
      upload "$src" "$dst" "$access" "$secret" '' "$verbose" "$dryrun"
      else
      source $dir/s3/download
      download "$src" "$dst" "$access" "$secret" '' "$verbose" "$dryrun"
      fi








      share|improve this question










      share|improve this question




      share|improve this question









      asked Jan 13 at 22:40









      Martin York

      70.9k481244




      70.9k481244




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          2
          down vote













          In case of errors/warnings, write your output to stderr and not just echo them to stdout stream. This might also include you returning the usage section.



          Having a chain of if block is imo, always very bad. You can use a switch-case block there, and keep shifting the arguments. A simple example would be:



          ARGS=()
          while [[ $# -gt 0 ]]
          do
          key="$1"

          case $key in
          -v|--verbose)
          verbose='/dev/stdout'
          shift # past argument
          ;;
          --dryrun)
          dryrun=1
          shift # past argument
          ;;
          -k=*|--key=*)
          access="$key#*="
          shift # past argument
          shift # past value
          ;;
          -k|--key)
          shift # past argument
          access="$1"
          shift # past value
          ;;
          .
          .
          .
          *) # unknown option
          if [[ "$key#-" != $key ]]; then
          badflag=1
          >&2 echo "Bad flag: $var"
          fi
          ARGS+=("$1") # save it in an array for later
          shift # past argument
          ;;
          esac
          done


          Notice how easily you can maintain the --key=KEY and --key KEY format parameters. Apart from that, it is really easy to later on add another new argument to your utility.



          Keep defining your globals in UPPER_CASE, so that it easy to distinguish them later in your ever-expanding code.




          echo "These can be set in the environment variables AMZ_ACCESS_KEY/AMZ_SECRET_KEY or passed with flags"



          AWS recommends having the environment variables named AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. I would consider it breaking the norm if you are not respecting defaults.



          Define the usage content (or man page?) as a heredoc:



          USAGE=<<EOF

          Usage:
          s3cp <file> <s3-url> [--key=<key>] [--secret=<secret>] [--verbose] [--dryrun]
          s3cp <s3-url> <file> [--key=<key>] [--secret=<secret>] [--verbose] [--dryrun]

          s3-url: s3://<bucket>/<Object-Path>

          EOF





          share|improve this answer























            Your Answer




            StackExchange.ifUsing("editor", function ()
            return StackExchange.using("mathjaxEditing", function ()
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            );
            );
            , "mathjax-editing");

            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "196"
            ;
            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: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );








             

            draft saved


            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f185068%2fs3-bash-tools-part-3%23new-answer', 'question_page');

            );

            Post as a guest






























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            2
            down vote













            In case of errors/warnings, write your output to stderr and not just echo them to stdout stream. This might also include you returning the usage section.



            Having a chain of if block is imo, always very bad. You can use a switch-case block there, and keep shifting the arguments. A simple example would be:



            ARGS=()
            while [[ $# -gt 0 ]]
            do
            key="$1"

            case $key in
            -v|--verbose)
            verbose='/dev/stdout'
            shift # past argument
            ;;
            --dryrun)
            dryrun=1
            shift # past argument
            ;;
            -k=*|--key=*)
            access="$key#*="
            shift # past argument
            shift # past value
            ;;
            -k|--key)
            shift # past argument
            access="$1"
            shift # past value
            ;;
            .
            .
            .
            *) # unknown option
            if [[ "$key#-" != $key ]]; then
            badflag=1
            >&2 echo "Bad flag: $var"
            fi
            ARGS+=("$1") # save it in an array for later
            shift # past argument
            ;;
            esac
            done


            Notice how easily you can maintain the --key=KEY and --key KEY format parameters. Apart from that, it is really easy to later on add another new argument to your utility.



            Keep defining your globals in UPPER_CASE, so that it easy to distinguish them later in your ever-expanding code.




            echo "These can be set in the environment variables AMZ_ACCESS_KEY/AMZ_SECRET_KEY or passed with flags"



            AWS recommends having the environment variables named AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. I would consider it breaking the norm if you are not respecting defaults.



            Define the usage content (or man page?) as a heredoc:



            USAGE=<<EOF

            Usage:
            s3cp <file> <s3-url> [--key=<key>] [--secret=<secret>] [--verbose] [--dryrun]
            s3cp <s3-url> <file> [--key=<key>] [--secret=<secret>] [--verbose] [--dryrun]

            s3-url: s3://<bucket>/<Object-Path>

            EOF





            share|improve this answer



























              up vote
              2
              down vote













              In case of errors/warnings, write your output to stderr and not just echo them to stdout stream. This might also include you returning the usage section.



              Having a chain of if block is imo, always very bad. You can use a switch-case block there, and keep shifting the arguments. A simple example would be:



              ARGS=()
              while [[ $# -gt 0 ]]
              do
              key="$1"

              case $key in
              -v|--verbose)
              verbose='/dev/stdout'
              shift # past argument
              ;;
              --dryrun)
              dryrun=1
              shift # past argument
              ;;
              -k=*|--key=*)
              access="$key#*="
              shift # past argument
              shift # past value
              ;;
              -k|--key)
              shift # past argument
              access="$1"
              shift # past value
              ;;
              .
              .
              .
              *) # unknown option
              if [[ "$key#-" != $key ]]; then
              badflag=1
              >&2 echo "Bad flag: $var"
              fi
              ARGS+=("$1") # save it in an array for later
              shift # past argument
              ;;
              esac
              done


              Notice how easily you can maintain the --key=KEY and --key KEY format parameters. Apart from that, it is really easy to later on add another new argument to your utility.



              Keep defining your globals in UPPER_CASE, so that it easy to distinguish them later in your ever-expanding code.




              echo "These can be set in the environment variables AMZ_ACCESS_KEY/AMZ_SECRET_KEY or passed with flags"



              AWS recommends having the environment variables named AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. I would consider it breaking the norm if you are not respecting defaults.



              Define the usage content (or man page?) as a heredoc:



              USAGE=<<EOF

              Usage:
              s3cp <file> <s3-url> [--key=<key>] [--secret=<secret>] [--verbose] [--dryrun]
              s3cp <s3-url> <file> [--key=<key>] [--secret=<secret>] [--verbose] [--dryrun]

              s3-url: s3://<bucket>/<Object-Path>

              EOF





              share|improve this answer

























                up vote
                2
                down vote










                up vote
                2
                down vote









                In case of errors/warnings, write your output to stderr and not just echo them to stdout stream. This might also include you returning the usage section.



                Having a chain of if block is imo, always very bad. You can use a switch-case block there, and keep shifting the arguments. A simple example would be:



                ARGS=()
                while [[ $# -gt 0 ]]
                do
                key="$1"

                case $key in
                -v|--verbose)
                verbose='/dev/stdout'
                shift # past argument
                ;;
                --dryrun)
                dryrun=1
                shift # past argument
                ;;
                -k=*|--key=*)
                access="$key#*="
                shift # past argument
                shift # past value
                ;;
                -k|--key)
                shift # past argument
                access="$1"
                shift # past value
                ;;
                .
                .
                .
                *) # unknown option
                if [[ "$key#-" != $key ]]; then
                badflag=1
                >&2 echo "Bad flag: $var"
                fi
                ARGS+=("$1") # save it in an array for later
                shift # past argument
                ;;
                esac
                done


                Notice how easily you can maintain the --key=KEY and --key KEY format parameters. Apart from that, it is really easy to later on add another new argument to your utility.



                Keep defining your globals in UPPER_CASE, so that it easy to distinguish them later in your ever-expanding code.




                echo "These can be set in the environment variables AMZ_ACCESS_KEY/AMZ_SECRET_KEY or passed with flags"



                AWS recommends having the environment variables named AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. I would consider it breaking the norm if you are not respecting defaults.



                Define the usage content (or man page?) as a heredoc:



                USAGE=<<EOF

                Usage:
                s3cp <file> <s3-url> [--key=<key>] [--secret=<secret>] [--verbose] [--dryrun]
                s3cp <s3-url> <file> [--key=<key>] [--secret=<secret>] [--verbose] [--dryrun]

                s3-url: s3://<bucket>/<Object-Path>

                EOF





                share|improve this answer















                In case of errors/warnings, write your output to stderr and not just echo them to stdout stream. This might also include you returning the usage section.



                Having a chain of if block is imo, always very bad. You can use a switch-case block there, and keep shifting the arguments. A simple example would be:



                ARGS=()
                while [[ $# -gt 0 ]]
                do
                key="$1"

                case $key in
                -v|--verbose)
                verbose='/dev/stdout'
                shift # past argument
                ;;
                --dryrun)
                dryrun=1
                shift # past argument
                ;;
                -k=*|--key=*)
                access="$key#*="
                shift # past argument
                shift # past value
                ;;
                -k|--key)
                shift # past argument
                access="$1"
                shift # past value
                ;;
                .
                .
                .
                *) # unknown option
                if [[ "$key#-" != $key ]]; then
                badflag=1
                >&2 echo "Bad flag: $var"
                fi
                ARGS+=("$1") # save it in an array for later
                shift # past argument
                ;;
                esac
                done


                Notice how easily you can maintain the --key=KEY and --key KEY format parameters. Apart from that, it is really easy to later on add another new argument to your utility.



                Keep defining your globals in UPPER_CASE, so that it easy to distinguish them later in your ever-expanding code.




                echo "These can be set in the environment variables AMZ_ACCESS_KEY/AMZ_SECRET_KEY or passed with flags"



                AWS recommends having the environment variables named AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. I would consider it breaking the norm if you are not respecting defaults.



                Define the usage content (or man page?) as a heredoc:



                USAGE=<<EOF

                Usage:
                s3cp <file> <s3-url> [--key=<key>] [--secret=<secret>] [--verbose] [--dryrun]
                s3cp <s3-url> <file> [--key=<key>] [--secret=<secret>] [--verbose] [--dryrun]

                s3-url: s3://<bucket>/<Object-Path>

                EOF






                share|improve this answer















                share|improve this answer



                share|improve this answer








                edited Jan 16 at 18:13


























                answered Jan 16 at 18:05









                hjpotter92

                4,98611539




                4,98611539






















                     

                    draft saved


                    draft discarded


























                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f185068%2fs3-bash-tools-part-3%23new-answer', 'question_page');

                    );

                    Post as a guest













































































                    Popular posts from this blog

                    Chat program with C++ and SFML

                    Function to Return a JSON Like Objects Using VBA Collections and Arrays

                    Will my employers contract hold up in court?