Skip to main content
combined two solution into a single one and added the solution provided by @Jay to the summary.
Source Link
Bruno K
  • 33
  • 1
  • 5
 

It was possible to solve the issue by using an array, as explained by @meuh. TheA solution forthat works in both bash and zsh is:

#!/usr/bin/env bash
transfer () {
    push () {
      if [[ args[${#args[*]}]="$1"
"$#" -eq 0 ]]; }then
    build () {
     echo "No arguments args=()specified."
        forreturn file1
        dofi
   
    local -a args
    push "-F"args=()
      for file in "$@"
   push "filedata=@$file"do
        done
   args+=("-F }filedata=@$file")
    build "$@"done

    curl --progress-bar -i "${args[@]}" https://transfer.sh | grep https
}

A similar approach can be taken withThe output in both zsh and bash is:

#!/usr/bin/env zsh
transfer ()$ {ls
    local -atest args
space.txt    args=()test'special.txt
   $ fortransfer filetest\ inspace.txt "$@"test\'special.txt
   ######################################################################## do100.0%
        args+="https://transfer.sh/z5R7y/test-F filedata=@$file"
    donespace.txt
    curl --progress-bar -i "${args[@]}" https://transfer.sh/z5R7y/testspecial.txt
$ |transfer grep*
######################################################################## 100.0%
https://transfer.sh/4GDQC/test-space.txt
}https://transfer.sh/4GDQC/testspecial.txt

The solution provided by @Jay also works perfectly well:

transfer() {
  printf -- "-F filedata=@%s\0" "$@" \
    | xargs -0 sh -c \ 
    'curl --progress-bar -i "$@" https://transfer.sh | grep -i https' zerop
}

It was possible to solve the issue by using an array, as explained by @meuh. The solution for bash is:

#!/usr/bin/env bash
transfer () {
    push () {
        args[${#args[*]}]="$1"
    }
    build () {
        args=()
        for file
        do
            push "-F"
            push "filedata=@$file"
        done
    }
    build "$@"
    curl --progress-bar -i "${args[@]}" https://transfer.sh | grep https
}

A similar approach can be taken with zsh:

#!/usr/bin/env zsh
transfer () {
    local -a args
    args=()
    for file in "$@"
    do
        args+="-F filedata=@$file"
    done
    curl --progress-bar -i "${args[@]}" https://transfer.sh | grep https
}
 

It was possible to solve the issue by using an array, as explained by @meuh. A solution that works in both bash and zsh is:

transfer () {
    if [[ "$#" -eq 0 ]]; then
        echo "No arguments specified."
        return 1
    fi
 
    local -a args
    args=()
    for file in "$@"
    do
        args+=("-F filedata=@$file")
    done

    curl --progress-bar -i "${args[@]}" https://transfer.sh | grep https
}

The output in both zsh and bash is:

$ ls
test space.txt    test'special.txt
$ transfer test\ space.txt test\'special.txt
######################################################################## 100.0%
https://transfer.sh/z5R7y/test-space.txt
https://transfer.sh/z5R7y/testspecial.txt
$ transfer *
######################################################################## 100.0%
https://transfer.sh/4GDQC/test-space.txt
https://transfer.sh/4GDQC/testspecial.txt

The solution provided by @Jay also works perfectly well:

transfer() {
  printf -- "-F filedata=@%s\0" "$@" \
    | xargs -0 sh -c \ 
    'curl --progress-bar -i "$@" https://transfer.sh | grep -i https' zerop
}
added solution for bash and zsh
Source Link
Bruno K
  • 33
  • 1
  • 5

Edit/Solution

It was possible to solve the issue by using an array, as explained by @meuh. The solution for bash is:

#!/usr/bin/env bash
transfer () {
    push () {
        args[${#args[*]}]="$1"
    }
    build () {
        args=()
        for file
        do
            push "-F"
            push "filedata=@$file"
        done
    }
    build "$@"
    curl --progress-bar -i "${args[@]}" https://transfer.sh | grep https
}

A similar approach can be taken with zsh:

#!/usr/bin/env zsh
transfer () {
    local -a args
    args=()
    for file in "$@"
    do
        args+="-F filedata=@$file"
    done
    curl --progress-bar -i "${args[@]}" https://transfer.sh | grep https
}

It might be a good idea to pipe the output of the function to the clipboard with xsel --clipboard or xclip on Linux and pbcopy on OS X.

Edit/Solution

It was possible to solve the issue by using an array, as explained by @meuh. The solution for bash is:

#!/usr/bin/env bash
transfer () {
    push () {
        args[${#args[*]}]="$1"
    }
    build () {
        args=()
        for file
        do
            push "-F"
            push "filedata=@$file"
        done
    }
    build "$@"
    curl --progress-bar -i "${args[@]}" https://transfer.sh | grep https
}

A similar approach can be taken with zsh:

#!/usr/bin/env zsh
transfer () {
    local -a args
    args=()
    for file in "$@"
    do
        args+="-F filedata=@$file"
    done
    curl --progress-bar -i "${args[@]}" https://transfer.sh | grep https
}

It might be a good idea to pipe the output of the function to the clipboard with xsel --clipboard or xclip on Linux and pbcopy on OS X.

Source Link
Bruno K
  • 33
  • 1
  • 5

posting data using cURL in a script

I'm trying to write a simple alternative script for uploading files to the transfer.sh service. One of the examples on the website mentions a way of uploading multiple files in a single "session":

$ curl -i -F filedata=@/tmp/hello.txt \
  -F filedata=@/tmp/hello2.txt https://transfer.sh/

I'm trying to make a function that would take any number of arguments (files) and pass them to cURL in such fashion. The function is as follows:

transfer() {
    build() {
        for file in $@
        do
            printf "-F filedata=@%q " $file
        done
    }

    curl --progress-bar -i \
        $(build $@) https://transfer.sh | grep https
}

The function works as expected as long as no spaces are in the filenames. The output of printf "-f filedata=@%q " "hello 1.txt" is -F filedata=@test\ 1.txt, so I expected the special characters to be escaped correctly. However, when the function is called with a filename that includes spaces:

$ transfer hello\ 1.txt

cURL does not seem to interpret the escapes and reports an error:

curl: (26) couldn't open file "test\"

I also tried quoting parts of the command, e.g. printf "-F filedata=@\"%s\" " "test 1.txt", which produces -F filedata=@"test 1.txt" . In such case cURL returns the same error: curl: (26) couldn't open file ""test". It seems that it does not care about quotes at all.

I'm not really sure what causes such behaviour. How could I fix the function to also work with filenames that include whitespace?