I am trying to copy the & sign to the clipboard using the code below. But it just gives me an error "| was unexpected at this time."
import os
def addToClipBoard(text):
command = 'echo ' text.strip() '| clip'
os.system(command)
addToClipBoard('&')
Is there a way to make it work with a little tweaking, or do I have to use another way?
CodePudding user response:
you running shell command to copy text to clip board but '&' sign in shell command is used to run command in background so maybe that's why it's not working.
you can directly copy text to clip board using python like this :
import pyperclip
pyperclip.copy('The text to be copied to the clipboard.')
code from here : Python script to copy text to clipboard
CodePudding user response:
You need to quote (or escape) the &
character:
import os
def addToClipBoard(text):
command = "echo '{}' | clip".format(text.strip())
os.system(command)
addToClipBoard('&')
In Bash, &
is a control operator. It’s a shell builtin, meaning, it’s literally a core part of the Bash tool set. (Copied from BashItOut - Ampersands & on the command line)
EDIT
As @CharlesDuffy mentioned in the comments, there's a better way of doing this for security reasons.
Consider the string $(rm -rf ~/*)'$(rm -rf ~/*)'
-- trying to copy it to the clipboard is going to result in a deleted home directory even with the extra quotes, because the quotes inside the string itself cancel them out.
The solution is to use shlex.quote()
as a safer means of adding literal quotes.
import os
import shlex
def addToClipBoard(text):
command = "printf '%s\n' {} | clip".format(shlex.quote(text))
os.system(command)
addToClipBoard('&')
NOTE: This last section is based on the comments by @CharlesDuffy.
CodePudding user response:
os.system
doesn't itself know that the |
character is supposed to redirect stdin, and depending on the OS it's not necessarily running your command through a shell that would do that. If you use subprocess
instead you can pass data to stdin directly, e.g.:
import subprocess
def add_to_clipboard(text: str) -> None:
subprocess.run("clip", text=True, input=text.strip())