Я пытался написать сценарий оболочки для копирования файлов. Вот что я сделал.
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
Выход из разделителя полей в переменной для предотвращения разделения слова не полезен: оболочка все еще разделит слова на разделителях, перечисленных в $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/