Почему cp не определяет '\' (обратный слеш + пробел)?

Я пытался написать сценарий оболочки для копирования файлов. Вот что я сделал.

 workingDirectory=$(pwd | sed "s/ /\\ /g")

Теперь echo $workingDirectory показывает /home/user/Documents/Learning and Development/.

Но я знаю, чтобы команда cp работала, мне нужно заменить пробелы на \ (обратная косая черта + пробел). Поэтому я немного изменил команду sed на

workingDirectory=$(pwd | sed "s/ /\\\ /g")

, так что echo $workingDirectory показывает /home/user/Documents/Learning\ and\ Development/. Все хорошо.

Но когда я пытаюсь использовать команду cp как,

cp $workingDirectory/jad/jad /usr/bin/

я получаю ошибки,

cp: cannot stat ‘/home/user/Documents/Learning\\’: No such file or directory
cp: cannot stat ‘and\\’: No such file or directory
cp: cannot stat ‘Development/jad/jad’: No such file or directory

В чем может быть причина? Как решить эту проблему?

РЕДАКТИРОВАТЬ

Если я использую первую команду sed, то ошибки

cp: cannot stat ‘/home/user/Documents/Learning’: No such file or directory
cp: cannot stat ‘and’: No such file or directory
cp: cannot stat ‘Development/jad/jad’: No such file or directory
3
задан 24 March 2016 в 12:45

1 ответ

Выход из разделителя полей в переменной для предотвращения разделения слова не полезен: оболочка все еще разделит слова на разделителях, перечисленных в $IFS:

~/tmp/directory with spaces$ workingDirectory=$(pwd | sed "s/ /\\\ /g")
~/tmp/directory with spaces$ echo $workingDirectory 
/home/user/tmp/directory\ with\ spaces
~/tmp/directory with spaces$ strace /bin/echo $workingDirectory |& grep '^execve'
execve("/bin/echo", ["/bin/echo", "/home/user/tmp/directory\\", "with\\", "spaces"], [/* 62 vars */]) = 0

, Таким образом, очевидное обходное решение для этого было бы установкой $IFS к пустой строке (и избегающий выходящих пробелов вообще), по существу отключив слово, разделяющее полностью:

~/tmp/directory with spaces$ workingDirectory=$(pwd)
~/tmp/directory with spaces$ echo $workingDirectory 
/home/user/tmp/directory with spaces
~/tmp/directory with spaces$ IFS=
~/tmp/directory with spaces$ strace -s 64 /bin/echo $workingDirectory |& grep '^execve'
execve("/bin/echo", ["/bin/echo", "/home/user/tmp/directory with spaces"], [/* 62 vars */]) = 0
~/tmp/directory with spaces$ stat $workingDirectory
  File: ‘/home/user/tmp/directory with spaces’
  Size: 4096        Blocks: 8          IO Block: 4096   directory
Device: 812h/2066d  Inode: 782086      Links: 2
Access: (0775/drwxrwxr-x)  Uid: ( 1000/    user)   Gid: ( 1000/    user)
Access: 2016-03-24 11:22:43.606332994 +0100
Modify: 2016-03-24 10:51:00.835689309 +0100
Change: 2016-03-24 10:51:00.835689309 +0100
 Birth: -

Однако отключающее слово, разделяющее полностью в целом, не имеет слишком большого смысла. Если у Вас нет серьезных оснований отключить слово, разделяющее полностью больше чем для одной команды, я предлагаю, чтобы Вы просто использовали двойные кавычки для предотвращения его ограничено к строкам, которые могут возможно содержать разделителей полей:

workingDirectory=$(pwd)
cp "$workingDirectory"/jad/jad /usr/bin/
3
ответ дан 24 March 2016 в 22:45
  • 1
    @andy - когда он загрузится в окна, у него будет та же проблема, если он не делает мою фиксацию – ravery 26 June 2017 в 06:01

Другие вопросы по тегам:

Похожие вопросы: