我总是很犹豫要不要乱来,$IFS
因为它正在破坏全球。
但通常它使将字符串加载到 bash 数组中变得漂亮而简洁,而对于 bash 脚本而言,简洁性是很难做到的。
因此,我认为如果我尝试将起始内容“保存”$IFS
到另一个变量中,然后在我完成$IFS
某项操作后立即恢复它,那可能总比没有好。
这个实用吗?或者它本质上是没有意义的,我应该直接IFS
回到它随后使用所需的任何东西?
大概这是我在 oh-my-zsh 设置中启用的某个插件提供的功能(我已经使用 zsh 很多年了)。
我注意到自从我将我的公钥添加到服务器(现在我可以在不输入密码的情况下通过 SSH 连接到服务器),当我scp
在我的 shell 中编写一个命令时,我实际上能够完成远程文件路径!
例如
$ diff <(scp Remoteuser@remote.domain.net:/var/www/html/
Run Code Online (Sandbox Code Playgroud)
我点击了标签,它就起作用了!(至于我试图用命令本身完成什么,我将使用scp
“复制”到标准输出,并将其作为文件提供给差异。这样我可以看到我在之前部署到服务器的确切更改运行rsync
)
我很好奇是什么部分使这项工作如此顺利。它是否内置于与 z shell 集成的 scp 中?或者是其他东西?
我大量使用命令行,多年来已从 迁移bash
到zsh
作为日常驱动程序外壳。我通常使用稍微定制的 oh-my-zsh 环境,但有些系统在 prezto 上;差异并不大。
我一直在为 zsh 使用的最高效的插件是zsh-syntax-highlighting
和history-substring-search
,最近我一直在使用非常强大的fzf
插件来提取历史记录。
现在,我发现命令行中对我来说最大的痛点之一是命令参数重新排序。我经常尝试运行命令
command very/long/filesystem/path/to/argumentA another/filesystem/or/network/path/argumentB
Run Code Online (Sandbox Code Playgroud)
并意识到我已经把订单倒过来了。
另一种更常见的情况是当我们执行任何“手动部署”工作流程时:首先将新内容与真实内容进行比较,例如
diff /opt/app/static/www/a.html /home/user/docs/dev/src/a.html
cp /home/user/docs/dev/src/a.html /opt/app/static/www/a.html
Run Code Online (Sandbox Code Playgroud)
好的,好的,最后一个例子(这个有几个步骤),我不再保证。完美的现实世界示例就在这里。让我们用一些可爱的人类大小的文件列表来破解:
find /pool/backups -type f -print0 | xargs -0 ls -lh > filelisting
Run Code Online (Sandbox Code Playgroud)
我想以交互方式排序和挑选一些大小:
sort -rhk5 filelisting | fzf -m > /these/are/the_chosen
Run Code Online (Sandbox Code Playgroud)
不错,有效!哦,但我现在只需要路径,但不想重新运行find
:
cut -d ' ' -f 10 /these/are/the_chosen
Run Code Online (Sandbox Code Playgroud)
输出是垃圾,因为我们遇到了ls -lh
对空格变得活泼的挫折。但我有一个策略:加入连续的空间。让我们选择tr -s
挤压空格字符,这里不需要正则表达式。虽然,tr
需要标准输入:
cat /these/are/the_chosen | tr -s ' …
Run Code Online (Sandbox Code Playgroud) 这个难题是由git pull
从 root运行引起的。
我这样做有多种原因......我希望我的设备在启动时更新代码,rc.local
并由 root 运行。
这一切都很好(npm install
当由 root 运行时往往会失败,但这是一个完整的“另一个主题”),当我尝试使用非 root 用户的 git 存储库之后,问题就出现了......一些 git 文件有由 root 编写,所以现在我不能再使用它了(权限被拒绝)。
所以我想递归地chown
返回它,但似乎没有任何东西真正适用于所有的小 git 文件。我尝试了-R
标志和./**/*
路径。
我的猜测是,这些技术都没有下降到点目录中。
观察:
$ ls
$ ls > list
$ cat list
list
Run Code Online (Sandbox Code Playgroud)
这似乎表明ls
执行时重定向到文件list
已经开始并且list
文件已经创建。无论如何,这是一个足够好的解释,但问题是:我怎样才能防止这种情况发生?我期望发生的是ls
将执行并将其输出转储到其中list
,这就是我想要的。
当尝试执行命令时,我在 shell 中遇到一种常见情况
command "/some/complex/and terrible/path" -vf --various --flags --and -- things --config-file="/some other/annoyingly/large/path/to/somewhere"
事实证明我大部分时间都在那里,但需要移动一些东西。假设我必须将最后一个参数一直移到前面才能尝试下一步。
command --config-file="/some other/annoyingly/large/path/to/somewhere" "/some/complex/and terrible/path" -vf --various --flags --and -- things
尝试用击键高尔夫来看待这个问题,这是一个可怕的情况。这实际上是一个噩梦般的 shell 命令输入场景,您必须重新输入(或复制并粘贴)几乎一半的命令。保持理智的最佳希望可能是使用外部编辑器[像这样]。
即便如此,Vim 还不够聪明,无法进行 arg 解析(因此没有快速的方法可以使用 eg 来取出最后一个 arg daW
,尽管考虑到 vim 的强大功能,应该可以在 8 个按键左右完成这项工作) 。
我认为这可能是一个不错的解决方法,因为我确实使用了很多软件来在 vim 中编辑文本,因为我使用它来完成所有编码。
但我想要的是,Zsh(甚至 Bash!)行编辑器是否可以以某种方式进行编程,让我可以将 arg 推到周围。有点像这样: https: //github.com/AndrewRadev/sideways.vim但是,当然,这个插件也不适用于空格分隔的 shell 参数。并且需要vim。
我对定向跳跃(这样我可以将光标放在--config-file
arg 上的某处,然后混搭 HopLeft 以将 arg 跳到左侧)或猛拉并粘贴(这样我可以将光标放在--config-file
arg上的某处)感到满意,将其拉出,按 home 转到前面并将其粘贴在后面)。
通过这种方式,我们可以通过将参数作为一个单元进行导航,而不是将单个字符作为一个单元进行导航,从而快速重构 shell 参数。它会大大加快一般命令编辑的速度。我非常关心这一点,因为我直接在 shell 中进行了异常大量的编码。
如果我们要进一步考虑这个想法,这将被实现为编辑器模式,我们将其称为参数编辑模式,其中光标在参数而不是字符上移动,并且可以将参数作为一个单元执行一组更完善的操作。
现在让我们回到现实。问题是:我可以通过编程方式使 zsh 删除我当前所在的 …
这次我curl http://npmjs.org/install.sh | sudo sh
从 dir运行了“信任”安装脚本/
。
$ which npm
/usr/local/bin/npm
$ npm
bash: /home/steven/local/bin/npm: No such file or directory
$ echo $PATH
/home/steven/local/bin:/home/steven/local/bin:/home/steven/local/bin:/home/steven/local/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
$ ls /home/steven/local/bin
node node-waf
$ ls /usr/local/bin
node node-waf npm npm_g npm-g
Run Code Online (Sandbox Code Playgroud)
似乎某个地方的某个脚本正在污染我的$PATH
. 我想知道的是,如果bash
在它查找的第一个目录中找不到该程序,它不是一直在查看$PATH
吗?应该可以在里面找到/usr/local/bin
!
npm
真的,真的似乎不想只是工作。我想我要去加载一个稍微旧的 Ubuntu 并再试一次......
cat a > b
Run Code Online (Sandbox Code Playgroud)
和
cp a b
Run Code Online (Sandbox Code Playgroud)
如果它们的所有意图和目的在功能上都相同,那么哪个更快?
问这个问题我有点不好意思,不过这个话题好像特别难找。
在 Linux 系统上,我几乎只使用终端,并通过终端模拟器使用 SSH 访问系统(最常来自 macOS)。
一般来说,当涉及终端多路复用器时,复制和粘贴代码片段和日志中的错误等是跨系统遍历缓冲区的棘手问题,这通常是通过终端仿真器自己的选择功能进行复制和使用客户端操作系统的粘贴缓冲区。这个问题与此无关。
我的问题是当我在单个 Linux 服务器上打开大量 vim 实例时。我处于运行级别 3 并且不运行 GUI。我没有可用的xclip,主要是没有安装X。
当我在这个工作流程中时,我发现需要猛拉文件的一部分并将它们粘贴到同一个删除框上的其他 vim 中。Vim 的内置缓冲区+
和*
复制/粘贴缓冲区不起作用。(vim 中的剪贴板编译选项在这些系统上未启用)
但是,有效的是,如果我在一个 vim 实例中拉取一些文本,退出它,然后打开另一个 vim 实例,然后粘贴就可以了。所以关于退出 vim 的一些东西会在某个地方保留缓冲区。我认为,如果我可以让这个系统实时运行而不必关闭 vim,那就太好了。我想避免必须在 yanks 和 deletes 上分层绑定来实现我自己的 yank/paste 实现。
我希望这会变成一根绳子,它本来应该是一支箭。但是,shell 吃掉了这个命令。我想知道echo A --> B
当你在 bash 或 zsh 中运行它时,shell 实际做了什么?
bash ×5
shell ×5
zsh ×4
command-line ×2
linux ×2
autocomplete ×1
chown ×1
line-editor ×1
ls ×1
path ×1
posix ×1
shell-script ×1
vim ×1