Як я можу використовувати повторно останній висновок з командного рядка?


43

Я хотів би знати, як повторно використовувати останній висновок з консолі, тобто:

pv-3:method Xavier$ python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
/Library/Python/2.6/site-packages
pv-3:method Xavier$ cd **LASTOUTPUT**

7
Ви не можете; є деякий вступне пояснення тут . Ваша найкраща ставка - запустити команду ще раз, як видно з двох відповідей, розміщених до цього часу.
Жил 'ТАК - перестань бути злим'

Ви не можете зафіксувати вихід, надісланий безпосередньо на такий пристрій, як /dev/tty, але це має бути можливість захопити все, що було надіслано stdoutабо stderr, що може бути адекватним.
Мікель

@ Gilles - якщо ви, звичайно, не використовуєте відповідь @ mattdm!
simon

@Gilles: але може бути оболонка, створена кимось, яка буде захоплювати (і пропускати) виходи команд і робити захоплені виходи доступними для користувача, щоб посилатися з його подальших команд. Можливо, є навіть деякі існуючі, не настільки популярні снаряди, які дозволяють зробити це з більш-менш ускладненнями ...
imz - Іван Захарящев

Відповіді:


39

Якщо припустити баш:

% python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
/usr/lib/python2.7/site-packages
% cd $(!!)
cd $(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")
% pwd
/usr/lib/python2.7/site-packages

1
Дякую! Не надто просто набрати, але це б'ється миша.
методофакція

2
Ви також можете використовувати зворотні посилання (які я не можу зрозуміти, як змусити цей інтерфейс не wikify) замість $ (), але я виявив, що мені незручно вдарити backtick-shift-1-shift-1-backtick , і я намагаюся ввійти в звичку використовувати $ (), коли це можливо для читабельності.
jsbillings

@jsbillings дивіться мою відповідь нижче. Я набрав \ "для відображення" у відповіді. І щоб відобразити "\", як звичайно, введіть "\\".
yasouser

3
+1 Мені було цікаво, як гніздо `backtick-commands`! cd $(dirname $(which python))я прийшов!
Ед Браннін

21
Просто примітка, пам’ятайте, що це повторення команди. Якщо ваша команда має побічні ефекти, це може не працювати для вас.
Багата Гомолка

13

Ще не згадано, використовуйте змінну:

dir=$( python -c ... )
cd "$dir"

3
Саме так. Оскільки це оболонка, люди часто забувають про мовні особливості, які надає Bash, такі як петлі та призначення.
Еван

можна просто сказатиcd $dir
temporary_user_name

3
@Aerovistae, цитати потрібні, якщо ви не знаєте, звідки береться значення:
glenn jackman

@glenn, (я знаю, це може бути зовсім інше питання, але якщо відповідь коротка :), чи можете ви пояснити більше / навести приклад, коли не використання лапок може порушити справи?
alexey

2
Канонічне пояснення - unix.stackexchange.com/questions/171346/…
glenn jackman

8

Всі інші рішення включають в себе зміну робочого процесу або запуск команди двічі, що може бути непридатним, якщо запускати тривалий час, або не повторюється (наприклад, він видаляє файл - повторне його створення призведе до іншого результату).

Тож ось складна ідея, якщо вона вам потрібна:

.bashrc

exec > >(tee -a ~/$$.out)

PROMPT_COMMAND='LASTLINE=$(tail -n 1 ~/$$.out)'

trap 'rm ~/$$.out' EXIT

баш-підказка

$ python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
/usr/lib/python2.6/dist-packages
$ cd $LASTLINE
$ pwd
/usr/lib/python2.6/dist-packages

У цьому є деякі проблеми, тому це просто покликане стартувати. Наприклад, вихідний файл ( ~/<pid>.out) може зрости дуже великим і заповнити ваш диск. Також вся ваша оболонка може перестати працювати, якщо teeвмирає.

Він може бути модифікований лише для того, щоб зафіксувати вихід з попередньої команди за допомогою preexecі precmdгаків у zsh, або емуляцію їх у bash, але описати тут складніше.


6
Основна ідея хороша, але реалізація - ні. Стандартний вихід у сеансі оболонки - це не термінал, а труба, що призведе до того, що деякі програми поводяться по-різному. Не буде синхронізації між записом в stdout і записом в stderr або прямим на tty, тому, наприклад, ви можете побачити вихід команди, що відображається після наступного запиту. Ви також не захистили teeвід сигналів (спробуйте натиснути Ctrl+Cта виконати кілька команд). Використовуйте scriptутиліту, яка не має жодної з цих проблем.
Жил "ТАК - перестань бути злим"

Добре знати! Я все ще працюю над основами мого командного рядка, тому це, можливо, для мене надлишок, плюс я хочу мати змогу використовувати його на будь-якому комп’ютері, але я запам'ятаю це, якщо я коли-небудь досягну хорошого рівня.
методофакція

8

Робочий проект для традиційної оболонки:

ttyid=$(readlink /proc/$$/fd/1)
\___/   \______/ \___/ |  |  |
  |         |      |   |  |  \- 0: stdin 
  |         |      |   |  |     1: stdout <- our interest
  |         |      |   |  |     2: stderr
  |         |      |   |  \- fd is, maybe, filedescriptor
  |         |      |   |
  |         |      |   \- $$ is the PID of the current process (shell,
  |         |      |      in our case)
  |         |      |
  |         |      \- you know, much runtime stuff is here
  |         |
  |         \- readlink extracts the symbolic link of /proc/$$/fd/1
  |            lrwx------ 1 stefan stefan 64 2011-03-18 09:11
  |            /proc/22159/fd/1 -> /dev/pts/4
  |
  \- /dev/tty3 for real shell, /dev/pts/3 for xterm

Тепер ми можемо перевести екран на файл. Потребує судо.

id=${ttyid//\/dev\/tty}
sudo cat /dev/vcs$id > screen.dump

Пропозиція screendump: так названа програма для мене більше не працює. Можливо, лише для старих ядер. / dev / pts / N теж не працював для мене. Можливо, у вас є якийсь факультативний MKDEV в / dev - я пам'ятаю про деяких /dev/cuaN, але я можу помилятися.

Ми хотіли б передавати вихід, а не використовувати screen.dump. Але якось це не працює - іноді він чекає ENTER.

Захоплення не є звичайним текстовим файлом із стрічками рядків, але, наприклад, з 80x50 символами в одній послідовності.

Щоб вибрати останні два рядки, 1 для виведення команди та один для рядка-підказки, я повертаю його, вибираю 160 символів, знову повертаю і вибираю 80.

rev vcs4.dat | sed 's/\(.\{160\}\).*/\1/g' | rev | sed 's/\(.\{80\}\).*/\1/g'

Про всяк випадок, коли ви коли-небудь замислювалися, навіщо існує revпрограма.

Критика:

  • Перші команди вводяться, таким чином переміщуючи рядок ahed. Ну - просто числовий вправа, щоб вибрати третій-останній рядок чи щось таке. Я працював переважно в іншому вікні.
  • Не всі мають екран 80х50. Ну так, ми знаємо. Для вашого задоволення є $ COLUMNS та $ ROWS.
  • Вихід не завжди внизу. Свіжа і молода шкаралупа може бути у верхніх рядах. Ну - просто так: Оцініть, яка оболонка працює. Який підказок використовується. Здійсніть деяке оперативне виявлення та знайдіть останній рядок із оболонкою-оболонкою. Рядок перед (або 2. перед) повинен містити каталог.

Перша схема робиться за допомогою обяснения.py


+1, змусив мене зробитиalias tee2tty='tee $(readlink /proc/$$/fd/1)'
Тобіас Кіенцлер

7

Спробуйте це:

$ cd $(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")
$ pwd
/Library/Python/2.6/site-packages

6

Отже, ось ось відповідь:

Якщо ви працюєте під X, виберіть потрібний вихід мишею, щоб скопіювати його, а потім клацніть середнім клавішею, щоб вставити його.

Якщо ви працюєте на текстовій консолі, ви можете зробити аналогічну річ із gpm .


1
+1 - хороша відповідь! ви можете досягти того ж, навіть якщо ви не запустите X, використовуючи екран GNU ( gnu.org/software/screen ).
симон

1
Це здавалося настільки очевидним, що я вагався сказати це. Але всі інші настільки зайняті бути розумними. :)
mattdm

тут єдина відповідь, яка дозволяє ОП повторно використовувати останній рядок - все інше тягне за собою повторне виконання команди, яка може бути в будь-якому місці між абсолютно неактуальними та катастрофічними :) Але ОП сказала повторне використання .
simon

@simon: Насправді моя відповідь не відповідає. Ні гленна.
Мікель

@Mikel: Це правда, але вони вимагають, щоб ви робили щось заздалегідь, або правильно в перший раз.
mattdm

1

(На жаль, це не робоча відповідь, але все ж щось цікаве. Хтось зацікавлений цілком може спробувати завершити реалізацію функції, про яку я вам розповім.)

У eshellвсередині Emacs, вони хотіли б мати таку можливість , але це не реалізовано в повному вигляді (який, проте , відбитий в документації ).

Наприклад:

~ $ pwd
~
~ $ /bin/echo $$
~
~ $ /bin/pwd
/home/imz
~ $ /bin/echo $$

~ $ 

Розумієте, у $$змінну може бути зафіксований лише вихід вбудованих модулів .

Але добре, деякі програми програмування elisp (див. eshell-mark-outputРеалізацію в "esh-mode.el"), і ви могли реалізувати функцію, яка "відзначає" останній вихід і повертає його як результат функції; так що ви можете використовувати цю функцію в команді eshell, про яку ви просите - функції elisp можна використовувати в командах eshell зі звичайним синтаксисом elisp, тобто в дужках, як це:

~ $ /bin/echo (buffer-name)
*eshell*
~ $ /bin/echo (car '(a b c))
a
~ $ 

0

Якщо ви усвідомлюєте, що хочете повторно використовувати результат перед ударом Enter, можете зберегти його у змінній: додайте tmp=$(на початку рядка та )в кінці. (Це видаляє будь-який порожній рядок в кінці виводу команди і фактично видаляє будь-який остаточний новий рядок; це рідко має значення.)

tmp=$(python -c )
echo "$tmp"
cd "$tmp"

Якщо ваша оболонка має ksh або zsh, ось корисну функцію, яку ви можете використовувати, щоб зробити це більш автоматичним. (Це не допомога в bash, оскільки для цього потрібна остання команда в конвеєрі, що виконується в батьківській оболонці, що є лише у ksh (не pdksh) та zsh.)

keep () {
  local line IFS=$'\n'
  kept=
  while read -r line; do
    printf '%s\n' "$line"
    kept=$kept$line$IFS
  done
}
alias keep=k

Використовуйте його таким чином:

python -c  |k
cd $kept

0
cd $(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()" | tee $(readlink /proc/$$/fd/1))

(нарощування відповіді 4485 )

Це дуже багато тексту, тому зробіть псевдонім:

alias tee2tty='tee $(readlink /proc/$$/fd/1)'

Тоді просто зателефонуйте cd $(python -c ... | tee2tty)

Це, звичайно, вимагає, щоб ви вже знали, що ви хочете зробити з результатом, але маєте перевагу викликати команду лише один раз.


0
$ cd \`python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"\`

зробить трюк.

Детальніше читайте тут: Заміна команд .


1
arumug: bahamat вже опублікував майже таку ж відповідь . Ваша версія з backticks не завжди працюватиме, якщо в команді вже є зворотні посилання.
Жил "ТАК - перестань бути злим"

0

Є краще рішення:

Просто надрукуйте !!після виконаної команди, і ви отримаєте повторний вихід.

Напр

введіть тут опис зображення

Оригінал:

https://askubuntu.com/questions/324423/how-to-access-the-last-return-value-in-bash


!!не повторює результат з останньої команди, вона запускає останню команду. Якщо jot -r 1 0 1000поверне одне випадкове число між 0 і 1000, то після запуску цієї команди один раз і отримання 539, запуску !!швидше за все дасть якесь інше число. !!також може бути небажаним, якщо попередня команда потребує значного часу для запуску або повторює операцію, яку не слід повторювати (наприклад, зміна файлу).
Калеб

1
приємний улов. Хоча існує простіший спосіб довести мене неправильно: echo $ RANDOM; !!
Тебе

Солодкий - не знав про це! Дякую.
Калеб
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.