0

I'm trying do symbolic links in Python, and on my tests it works ok, until it receives a path with spaces in the name. I change .py extension to .command to run in MacOS. The functionality is simple:

  1. The program asks to drag or type the path that I wish a symbolic link.
  2. Then asks the target path to create the link

  3. So finally, the link is created (of course if without spaces).

It works when there are no spaces in the path, so can anyone help me?

#!/usr/bin/env python

# Importa biblioteca os
import os

# Recebe path de origem e destino
source = str(input("Digite ou arraste a path Job: "))
target = str(input("Path para criação do link simbólico: "))
# Armazena último diretório em uma váriavel
last_dir = source.rsplit("/", 1)[1]

# Criação do link simbólico
if os.path.exists(source.strip()):
    try:
        link = target.strip()+"/"+last_dir.strip()
        print(link)
        # link.replace(" ","")
        os.symlink(source.strip(), link)
        print("Link criado com sucesso")
    except IOError as err:
        print(err)
else:
    print("Path inexistente")
AppyGG
  • 381
  • 1
  • 6
  • 12
  • 2
    if you use strip on the source, this will remove spaces at start and at the end, so source link becomes wrong. – Jean-François Fabre Nov 20 '19 at 15:41
  • The "last_dir = source.rsplit("/", 1)[1]" is to get the last name in path to use as a new name of a symbolic link. I can't modify the name or path, if have spaces I need to create the sym link as the source name, so I need the spaces on the final path. – Mario de Oliveira Nov 20 '19 at 15:48
  • One thing you could consider using is os.path to handle your splitting and combing of path strings. – Tom Myddeltyn Nov 20 '19 at 15:48
  • 1
    You are using `rsplit` to reimplement `os.path.basename`. – chepner Nov 20 '19 at 15:51
  • Even using `strip`, though, should only affect leading or trailing whitespace. Are you having a problem with names like `foo bar/baz.py` as well? – chepner Nov 20 '19 at 15:55
  • try to print the values before the link operation, and post here – Jean-François Fabre Nov 20 '19 at 16:03
  • @Jean-FrançoisFabre **_Digite ou arraste a path Job: /Users/mario/teste/Filme 1 Path para criação do link simbólico: /Users/mario/bleach /Users/mario/teste/Filme 1 /Users/mario/teste/Filme 1 /Users/mario/bleach/Filme 1 Link criado com sucesso_** If I run the code on PyCharm, it work! But I just found out that the problem is when I run on the MacOS terminal. Because when I drag the folder it recognizes space like: "\ " =/ – Mario de Oliveira Nov 20 '19 at 17:00
  • ah yes. It escapes the paths. In that case replace `\\ ` by nothing. – Jean-François Fabre Nov 20 '19 at 17:55
  • Yes @chepner, my problem is in the middle of the path when I run via terminal on MacOS – Mario de Oliveira Nov 21 '19 at 11:10
  • Replace \\ by nothing after read the path, right? – Mario de Oliveira Nov 21 '19 at 11:12
  • I would recommend not dragging a file to the terminal window. Doing so would make you need to detect in your Python code where it is running, so you would know whether or not you need to shell-parse the resulting string. Instead, right/control-click on the file, hold down the option key, and select 'Copy "" as Path'. This will let you paste the raw file name at your prompt. – chepner Nov 21 '19 at 13:58
  • [This Apple support note](https://support.apple.com/guide/terminal/drag-files-a-terminal-window-paths-trml106/mac) suggests that holding the command key while dragging prevents escaping. When I try, though, I simply get a suitably escaped invocation of the `cd` command. – chepner Nov 21 '19 at 14:01
  • Perfect @Jean-FrançoisFabre. Work! I'll post the final code. Thank you – Mario de Oliveira Nov 21 '19 at 15:41
  • @chepner Thank you for your attention. But this program is be used by users, so need to be simple and drag and drop. – Mario de Oliveira Nov 21 '19 at 15:43

2 Answers2

1

Thank you all to help me in this question. I needed to create new variables and use "nothing" to replace escapes "\" as @Jean-FrançoisFabre told.

My final code:

    #!/usr/bin/env python

import os

# Recebe path de origem
source = str(input("Digite ou arraste a path Job: "))
# Recebe path de destino
target = str(input("Path para criação do link simbólico: "))
# Filtra nome da última pasta e remove contrabarra
job = source.rsplit("/", 1)[1]
job2 = job.replace("\\", "")
# Remove contrabarra da path de origem e adiciona / no final da path para complementar depois
converted_path = source.replace("\\", "")
converted = (converted_path.strip()+"/")

# Criação do link simbólico
if os.path.exists(converted):
    try:
        os.symlink(converted.strip(), target.strip()+"/"+job2.strip())
        print("Link criado com sucesso")
    except IOError as err:
        print(err)
else:
    print("Path inexistente")
-3

If you are using Python 2, you could try substituting input method by raw_input, which will keep spaces for the string:

source = str(raw_input("Digite ou arraste a path Job: "))
target = str(raw_input("Path para criação do link simbólico: "))

See this answer for reference.

y.luis.rojo
  • 1,794
  • 4
  • 22
  • 41