Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I am trying to upload documents to my Microsoft OneDrive account using python-onedrive. The command I am using is this:

onedrive-cli put Long\ Filename\ 1.jpg
onedrive-cli put Long\ Filename\ 2.jpg

The problem is that there are a lot of these files, and I want to upload all of them (There is no option to upload an entire directory). I have using the asterisk but that doesn't work either:

user@office-debian:~/Desktop/docs$ onedrive-cli put *
usage: onedrive-cli [-h] [-c path] [-p] [-i] [-e enc] [--debug]

onedrive-cli: error: unrecognized arguments: Long Filename 1.jpg Long Filename 2.jpg

I presume this is because the program expects the spaces to be escaped, but the asterisk doesn't expand them that way. I have tried "piping" the arguments to no avail:

user@office-debian:~/Desktop/docs$ ls | onedrive-cli put
usage: onedrive-cli put [-h] [-n] file [folder]
onedrive-cli put: error: too few arguments

Evidently onedrive-cli doesn't recognise STDIN. Are there any other simple options left? I realise I could probably write a script but I was really hoping to avoid that!

The following seems to work, but it's not really what I had in mind:

for files in * ; do
  onedrive-cli put "$files"
share|improve this question

3 Answers 3

up vote 1 down vote accepted

If the following doesn't work...

cd ./target_dir
    set -- *
    onedrive-cli put "$@"

Then it's probably because you need a put for every argument in which case this might:

{    printf 'one-drive-cli' 
     printf " put ///%s///" *
} | sed 's|'\''|&"&"&|g;s|///|'\''|g' |
. /dev/stdin 

But if that doesn't work then your for loop probably is the best shell solution because your python script will only support one upload per invocation.

The best way to do it though is to edit the python script to meet your needs.

share|improve this answer
The script doesn't read file names from stdin. Even if it did, you're assuming that it uses ' to delimit file names, which is not necessarily the case, and in any case you'd need to worry about ' in file names (which is supported under Windows). –  Gilles Jun 10 at 1:00
@Gilles - what does Windows have to do with it? And I'm not feeding the script any lines from stdin. I think I don't understand what you mean. In any case the OP accepted the question only minutes after I posted it - I must have got something right. And I make no assumptions about the quotes - those hard'quotes are for the shell. True about ' in filenames though. But I was just trying to help out. –  mikeserv Jun 10 at 1:35
Oh, right, sorry, I'd misread. . /dev/stdin is a weird way of doing this — | sh would work just as well here. But my point about quoting stands: if a file name contains a ', your command will fail horribly — here, by executing a command chosen by whoever picked the file names. –  Gilles Jun 10 at 1:40
@Gilles - again, that's true. Maybe I'll fix that but I was hoping to get some feedback on what the actual deal was by now. In any case your Python bit is the bit - it's what I recommended OP do as well, even if I didn't have the skill to do it on my own - at least not trivially without hours of trial and error. –  mikeserv Jun 10 at 1:43
@Gilles - ok, I fixed the quote thing at least. –  mikeserv Jun 10 at 1:50
usage: onedrive-cli put [-h] [-n] file [folder]

This indicates that the subcommand put of the onedrive-cli program must have either one or two non-option arguments. A file is compulsory (the local file name to upload) and a folder is optional (a remote folder to upload to).

The command onedrive-cli put * passes the names of all files in the current directory as arguments. It works no matter what bizarre characters the file names may contain¹. The problem is that the onedrive-cli program doesn't accept multiple files as arguments, unlike many file manipulation commands.

The loop is the right way to do it:

for file in * ; do
  onedrive-cli put "$file"

The loop may be slow if the command has to authenticate to the server anew for every file. There doesn't seem to be a way to do better with the `onedrive-cli- tool as provided. You could write a few lines of Python (warning: completely untested! In particular I don't know how errors will be signaled.)

#!/usr/bin/env python
import sys
from onedrive import api_v5
api = api_v5.PersistentOneDriveAPI.from_conf({})
for f in sys.argv[1:]:

¹ Exception: for historical reasons, * omits files whose name begin with a . (dot files).

share|improve this answer

It may be easier to just cll it with find.

find ~/Desktop/docs -type f -exec overdrive-cli put {} \;

exec will take each file handle and feed it into the listed command. The {} denotes the file name, and the \; specifies the end of the exec. So you can even use the following if you want to make sure that each file is uploaded only once.

find ~/Desktop/docs -type f -exec overdrive-cli put {}; mv {} ~/Desktop/old-docs \;

The {} may need to be double-quoted to deal with spaces, but it is not likely.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.