Я могу придумать несколько сценариев.
zsh
нет в /etc/shells
,и OP хочет использовать его без ввода zsh
в командной строке. Возможные решения.
a )использовать трюки профиля, чтобы выполнить его при входе в систему. Это так же эффективно, как изменение оболочки.
b )попросить администратора добавить zsh
к /etc/shells
, чтобы вы могли chsh
к нему
c )умоляю админа сменить оболочку. это неразумно, потому что вы потеряете способность ftp
. вы можете использовать ftp
, только если у вас есть снаряд в/etc/shells
пользователь хочет выйти из ограниченной оболочки, скорее всего, rbash
или rsh
.
Если .profile
доступен для редактирования, PATH
можно расширить, отредактировав его. Как только /bin
окажется в пути, вы можете запустить bash
изнутри rsh/rbash
, получив доступ к команде chsh
, позволяющей менять оболочки. Многие команды имеют escape-последовательности оболочки, которые можно использовать для выхода из ограниченной оболочки и восстановления доступа к chsh
.
chsh
действительно не работает по какой-то другой причине. решение а из возможности 1 является ответом и здесь.
Сценарий 2 является единственной причиной, по которой действительно нужно изменить оболочку по умолчанию (, она слишком ограничена ).
Вы утверждаете, что последовательность команд, которую вы использовали, была:
echo "hello world" > test.txt;
echo "the large content that size is 1gb" >> test.txt;
sed -i ':a;N;$!ba;s/\n//g' test.txt;
Я предполагаю, что команды были на самом деле:
echo "hello world" > newfile;
cat test.txt >> newfile; # assuming the file with 1GigaByte was test.txt
И вы жалуетесь на команду sed, которая предназначена только для удаления новых строк (из вашего описания ).
То же самое можно сделать с tr
, который не использует (много )памяти:
echo "hello world" > newfile;
cat test.txt | tr -d '\n' >> newfile
И newfile
будет иметь копию test.txt с префиксом «hello world».
sed
не использует много памяти. Однако ОС может кэшировать диск. Поэтому использование nocache
может помочь (Если диск достаточно быстрый или вы не читаете одни и те же данные более одного раза ). И/или используйте опцию --unbuffered
для sed
(, чтобы sed
полагаться использовала как можно меньше памяти ).
Также не может быть опции эха, так как >>
выполняется оболочкой, а не командой. Он говорит оболочке добавить стандартный вывод команды к файлу.
И, как говорит @Kusalananda, ваш sed
скрипт неэффективен. Я бы, наверное, просто использовал cat.
uncache cat "<(echo the_prefix)" old_file_name > new_file_name
rm old_file_name
mv -T new_file_name old_file_name #note not all `mv`s have the `-T` option, it can unsafely be left out.
Если это убивает вашу память:
sed -i ':a;N;$!ba;s/\n//g' "test.txt"
затем, чтобы удалить новые строки, но читать только по одной, попробуйте:
{
printf "hello world" # with no newline
while IFS= read -r line || [ -n "$line" ]; do
printf "%s" "$line"
done < test.txt
echo "" # add a newline to the end of the file
} > test.txt.tmp && mv test.txt{.tmp,}
Это будет немного медленнее, чем sed, в обычных условиях, но ваша ситуация необычная.
Вам придется прочитать весь файл, чтобы добавить что-нибудь в начало файла. Однако вам не нужно считывать его в память, что делает ваша команда sed
.
Самым простым решением было бы просто объединить новое содержимое с существующим файлом, чтобы создать новый файл, а затем заменить исходный файл этим:
printf '%s\n' "new contents" | cat - test.txt >new-test.txt
mv new-test.txt test.txt
Здесь cat
сначала будет читать из своего стандартного потока ввода (из printf
или любой другой команды, которую вы можете использовать ), а затем из старого файла test.txt
. Вывод пойдет в файл new-test.txt
(, который будет создан или усечен, если он существовал ранее ).
Если вам абсолютно необходимо использовать для этого sed
:
sed '1i\
new contents
' test.txt >new-test.txt &&
mv new-test.txt
Это запускает команду вставки(i
)в первую строку файла и вставляет новое содержимое перед ней. Затем выводится остальная часть старого файла. Результат, как и прежде, записывается в new-test.txt
, который впоследствии мог заменить исходный файл.
Хотели бы вы сделать редактирование в -месте и иметь GNU sed
, вы могли бы написать его немного аккуратнее:
sed -i '1i new content' test.txt
В GNU sed
можно было вставлять несколько строк, используя \n
в качестве новой строки:
sed -i '1i new content\nsecond line' test.txt
Со стандартным sed
вы будете делать
sed '1i\
new content\
second line
' test.txt >new-test.txt &&
mv new-test.txt test.txt
Как насчет чего-нибудь попроще?
cat <<_eof_ > file
Hello world!
$(cat file)
_eof_
Или использовать ed
echo '0a
your text here
.
w' | ed some_file
Вы можете создать новый файл, содержащий «hello world», а затем добавить в него содержимое файла размером 1 Гб, используя DD (, который не будет читать весь файл сразу ).
echo -n 'hello world' > new_file.txt | dd if='1gb.txt' of='new_file.txt' bs=1 seek=$(wc -c <new_file.txt) && rm 1gb.txt
Источник:https://jamesdanielmarrsritchey.blogspot.com/2019/11/memory-friendly-way-of-prepending-data.html