44from typing import TYPE_CHECKING , Tuple
55
66import click
7+ import shlex
78from typing_extensions import Unpack
89
910from pyinfra import logger
@@ -118,6 +119,12 @@ def put_file(
118119 bool: Indicating success or failure
119120 """
120121
122+ if remote_filename .startswith ("~/" ):
123+ # Do not quote leading tilde to ensure that it gets properly expanded by the shell
124+ remote_filename = f"~/{ shlex .quote (remote_filename [2 :])} "
125+ else :
126+ remote_filename = QuoteString (remote_filename )
127+
121128 _ , temp_filename = mkstemp ()
122129
123130 try :
@@ -133,7 +140,7 @@ def put_file(
133140
134141 # Copy the file using `cp` such that we support sudo/su
135142 status , output = self .run_shell_command (
136- StringCommand ("cp" , temp_filename , QuoteString ( remote_filename ) ),
143+ StringCommand ("cp" , temp_filename , remote_filename ),
137144 print_output = print_output ,
138145 print_input = print_input ,
139146 ** arguments ,
@@ -146,6 +153,7 @@ def put_file(
146153
147154 if print_output :
148155 click .echo (
156+ # TODO: Check if the modification of remote_filename affects the output
149157 "{0}file copied: {1}" .format (self .host .print_prefix , remote_filename ),
150158 err = True ,
151159 )
0 commit comments