Search code examples
bashdockerargs

How can one pass an argument to docker run with spaces


This may be specific to the argument parsing done by https://github.com/atmoz/sftp/blob/master/entrypoint#L36

But I am trying to create a directory with spaces:

Some examples I've tried:


docker run -d  atmoz/sftp:alpine-3.7 user:password:::Inbound - Test Dir
...
[entrypoint] Parsing user data: "user:password:::Inbound"
Creating mailbox file: No such file or directory
[entrypoint] Creating directory: /home/user/Inbound
[entrypoint] Parsing user data: "-"
[entrypoint] ERROR: Invalid username "-", do not match required regex pattern: [A-Za-z0-9._][A-Za-z0-9._-]{0,31}

docker run -d atmoz/sftp:alpine-3.7 user:password:::"Inbound - Test Dir"
...
[entrypoint] Creating directory: /home/user/Inbound
[entrypoint] Creating directory: /home/user/-
[entrypoint] Creating directory: /home/user/Test
[entrypoint] Creating directory: /home/user/Dir

docker run -d atmoz/sftp:alpine-3.7 "user:password:::Inbound - Test Dir"
...
[entrypoint] Creating directory: /home/user/Inbound
[entrypoint] Creating directory: /home/user/-
[entrypoint] Creating directory: /home/user/Test
[entrypoint] Creating directory: /home/user/Dir

docker run -d atmoz/sftp:alpine-3.7 user:password:::Inbound\ -\ Test\ Dir
...
[entrypoint] Creating directory: /home/user/Inbound
[entrypoint] Creating directory: /home/user/-
[entrypoint] Creating directory: /home/user/Test
[entrypoint] Creating directory: /home/user/Dir

 docker run -d atmoz/sftp:alpine-3.7 user:password:::'Inbound - Test Dir'
...
[entrypoint] Creating directory: /home/user/Inbound
[entrypoint] Creating directory: /home/user/-
[entrypoint] Creating directory: /home/user/Test
[entrypoint] Creating directory: /home/user/Dir

Solution

  • It looks to me like this is a bug in the createUser function, due to lack of double-quotes around various variables containing the directory name. There's no way to work around this by adding escapes, quotes, etc in the argument; you really have to fix the script that's causing the problem.

    I haven't tested this, but adding double-quotes appropriately in lines 98-111 like this may do it:

    # Make sure dirs exists
    if [ -n "$dir" ]; then
        IFS=',' read -a dirArgs <<< "$dir"    # Quotes added here
        for dirPath in "${dirArgs[@]}"; do    # And here
            dirPath="/home/$user/$dirPath"
            if [ ! -d "$dirPath" ]; then
                log "Creating directory: $dirPath"
                mkdir -p "$dirPath"               # And here
                chown -R $uid:users "$dirPath"    # And here
            else
                log "Directory already exists: $dirPath"
            fi
        done
    fi
    

    It's possible there are other places in the script that're contributing to the problem, but at the very least the above changes need to be made. Also, the first line I added quotes to only needs them on some versions of bash, but it's best to have them there just in case.

    p.s. line 39 should probably also be fixed:

    IFS=':' read -a args <<< "$1"
    

    The current version uses $@, which is just weird. The function only ever gets passed one argument, and some versions of bash will misparse that if it's not quoted, so the version I have is a better way to do it.

    shellcheck.net points out a bunch of other dubious things, but that's the only other one I see that should matter.