mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-01-25 23:11:02 +08:00
Merge remote-tracking branch 'LCTT/master'
This commit is contained in:
commit
a8ec768d9d
@ -1,7 +1,7 @@
|
||||
language: c
|
||||
script:
|
||||
- sh ./scripts/check.sh
|
||||
- ./scripts/badge.sh
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then sh ./scripts/check.sh; fi'
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then sh ./scripts/badge.sh; fi'
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
@ -1,3 +1,4 @@
|
||||
### fuzheng1998 reapplying
|
||||
10 Games You Can Play on Linux with Wine
|
||||
======
|
||||
![](https://www.maketecheasier.com/assets/uploads/2017/09/wine-games-feat.jpg)
|
||||
|
@ -1,4 +1,3 @@
|
||||
Translating by bayar199468
|
||||
7 Best eBook Readers for Linux
|
||||
======
|
||||
**Brief:** In this article, we are covering some of the best ebook readers for Linux. These apps give a better reading experience and some will even help in managing your ebooks.
|
||||
|
@ -1,253 +0,0 @@
|
||||
Translating by cycoe...
|
||||
cycoe 翻译中
|
||||
24 Must Have Essential Linux Applications In 2017
|
||||
======
|
||||
Brief: What are the must have applications for Linux? The answer is subjective and it depends on for what purpose do you use your desktop Linux. But there are still some essentials Linux apps that are more likely to be used by most Linux user. We have listed such best Linux applications that you should have installed in every Linux distribution you use.
|
||||
|
||||
The world of Linux, everything is full of alternatives. You have to choose a distro? You have got several dozens of them. Are you trying to find a decent music player? Alternatives are there too.
|
||||
|
||||
But not all of them are built with the same thing in mind – some of them might target minimalism while others might offer tons of features. Finding the right application for your needs can be quite confusing and a tiresome task. Let’s make that a bit easier.
|
||||
|
||||
### Best free applications for Linux users
|
||||
|
||||
I’m putting together a list of essential free Linux applications I prefer to use in different categories. I’m not saying that they are the best, but I have tried lots of applications in each category and finally liked the listed ones better. So, you are more than welcome to mention your favorite applications in the comment section.
|
||||
|
||||
We have also compiled a nice video of this list. Do subscribe to our YouTube channel for more such educational Linux videos:
|
||||
|
||||
### Web Browser
|
||||
|
||||
![Web Browsers](https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Web-Browser-1024x512.jpg)
|
||||
[Save][1]Web Browsers
|
||||
|
||||
#### [Google Chrome][12]
|
||||
|
||||
Google Chrome is a powerful and complete solution for a web browser. It comes with excellent syncing capabilities and offers a vast collection of extensions. If you are accustomed to Google eco-system Google Chrome is for you without any doubt. If you prefer a more open source solution, you may want to try out [Chromium][13], which is the project Google Chrome is based on.
|
||||
|
||||
#### [Firefox][14]
|
||||
|
||||
If you are not a fan of Google Chrome, you can try out Firefox. It’s been around for a long time and is a very stable and robust web browser.
|
||||
|
||||
#### [Vivaldi][15]
|
||||
|
||||
However, if you want something new and different, you can check out Vivaldi. Vivaldi takes a completely fresh approach towards web browser. It’s from former team members of Opera and built on top of the Chromium project. It’s lightweight and customizable. Though it is still quite new and still missing out some features, it feels amazingly refreshing and does a really decent job.
|
||||
|
||||
[Suggested read[Review] Otter Browser Brings Hope To Opera Lovers][40]
|
||||
|
||||
### Download Manager
|
||||
|
||||
![Download Managers](https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Download-Manager-1024x512.jpg)
|
||||
[Save][2]Download Managers
|
||||
|
||||
#### [uGet][16]
|
||||
|
||||
uGet is the best download manager I have come across. It is open source and offers everything you can expect from a download manager. uGet offers advanced settings for managing downloads. It can queue and resume downloads, use multiple connections for downloading large files, download files to different directories according to categories and so on.
|
||||
|
||||
#### [XDM][17]
|
||||
|
||||
Xtreme Download Manager (XDM) is a powerful and open source tool developed with Java. It has all the basic features of a download manager, including – video grabber, smart scheduler and browser integration.
|
||||
|
||||
[Suggested read4 Best Download Managers For Linux][41]
|
||||
|
||||
### BitTorrent Client
|
||||
|
||||
![BitTorrent Clients](https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-BitTorrent-Client-1024x512.jpg)
|
||||
[Save][3]BitTorrent Clients
|
||||
|
||||
#### [Deluge][18]
|
||||
|
||||
Deluge is a open source BitTorrent client. It has a beautiful user interface. If you are used to using uTorrent for Windows, Deluge interface will feel familiar. It has various configuration options as well as plugins support for various tasks.
|
||||
|
||||
#### [Transmission][19]
|
||||
|
||||
Transmission takes the minimal approach. It is an open source BitTorrent client with a minimal user interface. Transmission comes pre-installed with many Linux distributions.
|
||||
|
||||
[Suggested readTop 5 Torrent Clients For Ubuntu Linux][42]
|
||||
|
||||
### Cloud Storage
|
||||
|
||||
![Cloud Storages](https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Cloud-Storage-1024x512.jpg)
|
||||
[Save][4]Cloud Storages
|
||||
|
||||
#### [Dropbox][20]
|
||||
|
||||
Dropbox is one of the most popular cloud storage service available out there. It gives you 2GB free storage to start with. Dropbox has a robust and straight-forward Linux client.
|
||||
|
||||
#### [MEGA][21]
|
||||
|
||||
MEGA offers 50GB of free storage. But that is not the best thing about it. The best thing about MEGA is that it has end-to-end encryption support for your files. MEGA has a solid Linux client named MEGAsync.
|
||||
|
||||
[Suggested readBest Free Cloud Services For Linux in 2017][43]
|
||||
|
||||
### Communication
|
||||
|
||||
![Communication Apps](https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Communication-1024x512.jpg)
|
||||
[Save][5]Communication Apps
|
||||
|
||||
#### [Pidgin][22]
|
||||
|
||||
Pidgin is an open source instant messenger client. It supports many chatting platforms including – Google Talk, Yahoo and even IRC. Pidgin is extensible through third-party plugins, that can provide a lot of additional functionalities to Pidgin.
|
||||
|
||||
You can also use [Franz][23] or [Rambox][24] to use several messaging services in one application.
|
||||
|
||||
#### [Skype][25]
|
||||
|
||||
We all know Skype, it is one of the most popular video chatting platforms. Recently it has [released a brand new desktop client][26] for Linux.
|
||||
|
||||
[Suggested read6 Best Messaging Apps Available For Linux In 2017][44]
|
||||
|
||||
### Office Suite
|
||||
|
||||
![Office Suites](https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Office-Suite-1024x512.jpg)
|
||||
[Save][6]Office Suites
|
||||
|
||||
#### [LibreOffice][27]
|
||||
|
||||
LibreOffice is the most actively developed open source office suite for Linux. It has mainly six modules – Writer, Calc, Impress, Draw, Math and Base. And every one of them supports a wide range of file formats. LibreOffice also supports third-party extensions. It is the default office suite for many of the Linux distributions.
|
||||
|
||||
#### [WPS Office][28]
|
||||
|
||||
If you want to try out something other than LibreOffice, WPS Office might be your go-to. WPS Office suite includes writer, presentation and spreadsheets support.
|
||||
|
||||
[Suggested read6 Best Open Source Alternatives to Microsoft Office for Linux][45]
|
||||
|
||||
### Music Player
|
||||
|
||||
![Music Players](https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Music-Player-1024x512.jpg)
|
||||
[Save][7]Music Players
|
||||
|
||||
#### [Lollypop][29]
|
||||
|
||||
This is a relatively new music player. Lollypop is open source and has a beautiful yet simple user interface. It offers a nice music organizer, scrobbling support, online radio and a party mode. Though it is a simple music player without so many advanced features, it is worth giving it a try.
|
||||
|
||||
#### [Rhythmbox][30]
|
||||
|
||||
Rhythmbox is the music player mainly developed for GNOME desktop environment but it works on other desktop environments as well. It does all the basic tasks of a music player, including – CD Ripping & Burning, scribbling etc. It also has support for iPod.
|
||||
|
||||
#### [cmus][31]
|
||||
|
||||
If you want minimalism and love your terminal window, cmus is for you. Personally, I’m a fan and user of this one. cmus is a small, fast and powerful console music player for Unix-like operating systems. It has all the basic music player features. And you can also extend its functionalities with additional extensions and scripts.
|
||||
|
||||
[Suggested readHow To Install Tomahawk Player In Ubuntu 14.04 And Linux Mint 17][46]
|
||||
|
||||
### Video Player
|
||||
|
||||
![Video Player](https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Video-Player-1024x512.jpg)
|
||||
[Save][8]Video Players
|
||||
|
||||
#### [VLC][32]
|
||||
|
||||
VLC is an open source media player. It is simple, fast, lightweight and really powerful. VLC can play almost any media formats you can throw at it out-of-the-box. It can also stream online medias. It also have some nifty extensions for various tasks like downloading subtitles right from the player.
|
||||
|
||||
#### [Kodi][33]
|
||||
|
||||
Kodi is a full-fledged media center. Kodi is open source and very popular among its user base. It can handle videos, music, pictures, podcasts and even games, from both local and network media storage. You can even record TV with it. The behavior of Kodi can be customized via add-ons and skins.
|
||||
|
||||
[Suggested read4 Format Factory Alternative In Linux][47]
|
||||
|
||||
### Photo Editor
|
||||
|
||||
![Photo Editors](https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Photo-Editor-1024x512.jpg)
|
||||
[Save][9]Photo Editors
|
||||
|
||||
#### [GIMP][34]
|
||||
|
||||
GIMP is the Photoshop alternative for Linux. It is open source, full-featured and professional photo editing software. It is packed with a wide range of tools for manipulating images. And on top of that, there is various customization options and third-party plugins for enhancing the experience.
|
||||
|
||||
#### [Krita][35]
|
||||
|
||||
Krita is mainly a painting tool but serves as a photo editing application as well. It is open source and packed with lots of sophisticated and advanced tools.
|
||||
|
||||
[Suggested readBest Photo Applications For Linux][48]
|
||||
|
||||
### Text Editor
|
||||
|
||||
Every Linux distribution comes with their own solution for text editors. Generally, they are quite simple and without much functionality. But here are some text editors with enhanced capabilities.
|
||||
|
||||
![Text Editors](https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Text-Editor-1024x512.jpg)
|
||||
[Save][10]Text Editors
|
||||
|
||||
#### [Atom][36]
|
||||
|
||||
Atom is the modern and hackable text editor maintained by GitHub. It is completely open-source and offers everything you can think of to get out of a text editor. You can use it right out-of-the-box or you can customize and tune it just the way you want. And it has a ton of extensions and themes from the community up for grab.
|
||||
|
||||
#### [Sublime Text][37]
|
||||
|
||||
Sublime Text is one of the most popular text editors. Though it is not free, it allows you to use the software for evaluation without any time limit. Sublime Text is a feature-rich and sophisticated piece of software. And of course, it has plugins and themes support.
|
||||
|
||||
[Suggested read4 Best Modern Open Source Code Editors For Linux][49]
|
||||
|
||||
### Launcher
|
||||
|
||||
![Launchers](https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Launcher-1024x512.jpg)
|
||||
[Save][11]Launchers
|
||||
|
||||
#### [Albert][38]
|
||||
|
||||
Albert is inspired by Alfred (a productivity application for Mac, which is totally kickass by-the-way) and still in the development phase. Albert is fast, extensible and customizable. The goal is to “Access everything with virtually zero effort”. It integrates with your Linux distribution nicely and helps you to boost your productivity.
|
||||
|
||||
#### [Synapse][39]
|
||||
|
||||
Synapse has been around for years. It’s a simple launcher that can search and run applications. It can also speed up various workflows like – controlling music, searching files, directories, bookmarks etc., running commands and such.
|
||||
|
||||
As Abhishek advised, we will keep this list of best Linux software updated with our readers’ (i.e. yours) feedback. So, what are your favorite must have Linux applications? Share with us and do suggest more categories of software to add to this list.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/essential-linux-applications/
|
||||
|
||||
作者:[Munif Tanjim][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://itsfoss.com/author/munif/
|
||||
[1]:http://pinterest.com/pin/create/bookmarklet/?media=https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Web-Browser-1024x512.jpg&url=https://itsfoss.com/essential-linux-applications/&is_video=false&description=Web%20Browsers
|
||||
[2]:http://pinterest.com/pin/create/bookmarklet/?media=https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Download-Manager-1024x512.jpg&url=https://itsfoss.com/essential-linux-applications/&is_video=false&description=Download%20Managers
|
||||
[3]:http://pinterest.com/pin/create/bookmarklet/?media=https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-BitTorrent-Client-1024x512.jpg&url=https://itsfoss.com/essential-linux-applications/&is_video=false&description=BitTorrent%20Clients
|
||||
[4]:http://pinterest.com/pin/create/bookmarklet/?media=https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Cloud-Storage-1024x512.jpg&url=https://itsfoss.com/essential-linux-applications/&is_video=false&description=Cloud%20Storages
|
||||
[5]:http://pinterest.com/pin/create/bookmarklet/?media=https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Communication-1024x512.jpg&url=https://itsfoss.com/essential-linux-applications/&is_video=false&description=Communication%20Apps
|
||||
[6]:http://pinterest.com/pin/create/bookmarklet/?media=https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Office-Suite-1024x512.jpg&url=https://itsfoss.com/essential-linux-applications/&is_video=false&description=Office%20Suites
|
||||
[7]:http://pinterest.com/pin/create/bookmarklet/?media=https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Music-Player-1024x512.jpg&url=https://itsfoss.com/essential-linux-applications/&is_video=false&description=Music%20Players
|
||||
[8]:http://pinterest.com/pin/create/bookmarklet/?media=https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Video-Player-1024x512.jpg&url=https://itsfoss.com/essential-linux-applications/&is_video=false&description=Video%20Player
|
||||
[9]:http://pinterest.com/pin/create/bookmarklet/?media=https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Photo-Editor-1024x512.jpg&url=https://itsfoss.com/essential-linux-applications/&is_video=false&description=Photo%20Editors
|
||||
[10]:http://pinterest.com/pin/create/bookmarklet/?media=https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Text-Editor-1024x512.jpg&url=https://itsfoss.com/essential-linux-applications/&is_video=false&description=Text%20Editors
|
||||
[11]:http://pinterest.com/pin/create/bookmarklet/?media=https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Launcher-1024x512.jpg&url=https://itsfoss.com/essential-linux-applications/&is_video=false&description=Launchers
|
||||
[12]:https://www.google.com/chrome/browser
|
||||
[13]:https://www.chromium.org/Home
|
||||
[14]:https://www.mozilla.org/en-US/firefox
|
||||
[15]:https://vivaldi.com
|
||||
[16]:http://ugetdm.com/
|
||||
[17]:http://xdman.sourceforge.net/
|
||||
[18]:http://deluge-torrent.org/
|
||||
[19]:https://transmissionbt.com/
|
||||
[20]:https://www.dropbox.com
|
||||
[21]:https://mega.nz/
|
||||
[22]:https://www.pidgin.im/
|
||||
[23]:https://itsfoss.com/franz-messaging-app/
|
||||
[24]:http://rambox.pro/
|
||||
[25]:https://www.skype.com
|
||||
[26]:https://itsfoss.com/skpe-alpha-linux/
|
||||
[27]:https://www.libreoffice.org
|
||||
[28]:https://www.wps.com
|
||||
[29]:http://gnumdk.github.io/lollypop-web/
|
||||
[30]:https://wiki.gnome.org/Apps/Rhythmbox
|
||||
[31]:https://cmus.github.io/
|
||||
[32]:http://www.videolan.org
|
||||
[33]:https://kodi.tv
|
||||
[34]:https://www.gimp.org/
|
||||
[35]:https://krita.org/en/
|
||||
[36]:https://atom.io/
|
||||
[37]:http://www.sublimetext.com/
|
||||
[38]:https://github.com/ManuelSchneid3r/albert
|
||||
[39]:https://launchpad.net/synapse-project
|
||||
[40]:https://itsfoss.com/otter-browser-review/
|
||||
[41]:https://itsfoss.com/4-best-download-managers-for-linux/
|
||||
[42]:https://itsfoss.com/best-torrent-ubuntu/
|
||||
[43]:https://itsfoss.com/cloud-services-linux/
|
||||
[44]:https://itsfoss.com/best-messaging-apps-linux/
|
||||
[45]:https://itsfoss.com/best-free-open-source-alternatives-microsoft-office/
|
||||
[46]:https://itsfoss.com/install-tomahawk-ubuntu-1404-linux-mint-17/
|
||||
[47]:https://itsfoss.com/format-factory-alternative-linux/
|
||||
[48]:https://itsfoss.com/image-applications-ubuntu-linux/
|
||||
[49]:https://itsfoss.com/best-modern-open-source-code-editors-for-linux/
|
@ -1,261 +0,0 @@
|
||||
FSSlc translating
|
||||
|
||||
How To Find The Mounted Filesystem Type In Linux
|
||||
======
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2018/07/filesystem-720x340.png)
|
||||
|
||||
As you may already know, the Linux supports numerous filesystems, such as Ext4, ext3, ext2, sysfs, securityfs, FAT16, FAT32, NTFS, and many. The most commonly used filesystem is Ext4. Ever wondered what type of filesystem are you currently using in your Linux system? No? Worry not! We got your back. This guide explains how to find the mounted filesystem type in Unix-like operating systems.
|
||||
|
||||
### Find The Mounted Filesystem Type In Linux
|
||||
|
||||
There can be many ways to find the filesystem type in Linux. Here, I have given 8 different methods. Let us get started, shall we?
|
||||
|
||||
#### Method 1 – Using findmnt command
|
||||
|
||||
This is the most commonly used method to find out the type of a filesystem. The **findmnt** command will list all mounted filesystems or search for a filesystem. The findmnt command can be able to search in **/etc/fstab** , **/etc/mtab** or **/proc/self/mountinfo**.
|
||||
|
||||
findmnt command comes pre-installed in most Linux distributions, because it is part of the package named **util-linux**. Just in case if it is not available, simply install this package and you’re good to go. For instance, you can install **util-linux** package in Debian-based systems using command:
|
||||
```
|
||||
$ sudo apt install util-linux
|
||||
|
||||
```
|
||||
|
||||
Let us go ahead and see how to use findmnt command to find out the mounted filesystems.
|
||||
|
||||
If you run it without any arguments/options, it will list all mounted filesystems in a tree-like format as shown below.
|
||||
```
|
||||
$ findmnt
|
||||
|
||||
```
|
||||
|
||||
**Sample output:**
|
||||
|
||||
![][2]
|
||||
|
||||
As you can see, the findmnt command displays the target mount point (TARGET), source device (SOURCE), file system type (FSTYPE), and relevant mount options, like whether the filesystem is read/write or read-only. (OPTIONS). In my case, my root(/) filesystem type is EXT4.
|
||||
|
||||
If you don’t like/want to display the output in tree-like format, use **-l** flag to display in simple, plain format.
|
||||
```
|
||||
$ findmnt -l
|
||||
|
||||
```
|
||||
|
||||
![][3]
|
||||
|
||||
You can also list a particular type of filesystem, for example **ext4** , using **-t** option.
|
||||
```
|
||||
$ findmnt -t ext4
|
||||
TARGET SOURCE FSTYPE OPTIONS
|
||||
/ /dev/sda2 ext4 rw,relatime,commit=360
|
||||
└─/boot /dev/sda1 ext4 rw,relatime,commit=360,data=ordered
|
||||
|
||||
```
|
||||
|
||||
Findmnt can produce df style output as well.
|
||||
```
|
||||
$ findmnt --df
|
||||
|
||||
```
|
||||
|
||||
Or
|
||||
```
|
||||
$ findmnt -D
|
||||
|
||||
```
|
||||
|
||||
Sample output:
|
||||
```
|
||||
SOURCE FSTYPE SIZE USED AVAIL USE% TARGET
|
||||
dev devtmpfs 3.9G 0 3.9G 0% /dev
|
||||
run tmpfs 3.9G 1.1M 3.9G 0% /run
|
||||
/dev/sda2 ext4 456.3G 342.5G 90.6G 75% /
|
||||
tmpfs tmpfs 3.9G 32.2M 3.8G 1% /dev/shm
|
||||
tmpfs tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
|
||||
bpf bpf 0 0 0 - /sys/fs/bpf
|
||||
tmpfs tmpfs 3.9G 8.4M 3.9G 0% /tmp
|
||||
/dev/loop0 squashfs 82.1M 82.1M 0 100% /var/lib/snapd/snap/core/4327
|
||||
/dev/sda1 ext4 92.8M 55.7M 30.1M 60% /boot
|
||||
tmpfs tmpfs 788.8M 32K 788.8M 0% /run/user/1000
|
||||
gvfsd-fuse fuse.gvfsd-fuse 0 0 0 - /run/user/1000/gvfs
|
||||
|
||||
```
|
||||
|
||||
You can also display filesystems for a specific device, or mountpoint too.
|
||||
|
||||
Search for a device:
|
||||
```
|
||||
$ findmnt /dev/sda1
|
||||
TARGET SOURCE FSTYPE OPTIONS
|
||||
/boot /dev/sda1 ext4 rw,relatime,commit=360,data=ordered
|
||||
|
||||
```
|
||||
|
||||
Search for a mountpoint:
|
||||
```
|
||||
$ findmnt /
|
||||
TARGET SOURCE FSTYPE OPTIONS
|
||||
/ /dev/sda2 ext4 rw,relatime,commit=360
|
||||
|
||||
```
|
||||
|
||||
You can even find filesystems with specific label:
|
||||
```
|
||||
$ findmnt LABEL=Storage
|
||||
|
||||
```
|
||||
|
||||
For more details, refer the man pages.
|
||||
```
|
||||
$ man findmnt
|
||||
|
||||
```
|
||||
|
||||
The findmnt command is just enough to find the type of a mounted filesystem in Linux. It is created for that specific purpose only. However, there are also few other ways available to find out the filesystem type. If you’re interested to know, read on.
|
||||
|
||||
#### Method 2 – Using blkid command
|
||||
|
||||
The **blkid** command is used locate and print block device attributes. It is also part of the util-linux package, so you don’t bother to install it.
|
||||
|
||||
To find out the type of a filesystem using blkid command, run:
|
||||
```
|
||||
$ blkid /dev/sda1
|
||||
|
||||
```
|
||||
|
||||
#### Method 3 – Using df command
|
||||
|
||||
The **df** command is used to report filesystem disk space usage in Unix-like operating systems. To find the type of all mounted filesystems, simply run:
|
||||
```
|
||||
$ df -T
|
||||
|
||||
```
|
||||
|
||||
**Sample output:**
|
||||
|
||||
![][4]
|
||||
|
||||
For details about df command, refer the following guide.
|
||||
|
||||
Also, check man pages.
|
||||
```
|
||||
$ man df
|
||||
|
||||
```
|
||||
|
||||
#### Method 4 – Using file command
|
||||
|
||||
The **file** command determines the type of a specified file. It works just fine for files with no file extension.
|
||||
|
||||
Run the following command to find the filesystem type of a partition:
|
||||
```
|
||||
$ sudo file -sL /dev/sda1
|
||||
[sudo] password for sk:
|
||||
/dev/sda1: Linux rev 1.0 ext4 filesystem data, UUID=83a1dbbf-1e15-4b45-94fe-134d3872af96 (needs journal recovery) (extents) (large files) (huge files)
|
||||
|
||||
```
|
||||
|
||||
Check man pages for more details:
|
||||
```
|
||||
$ man file
|
||||
|
||||
```
|
||||
|
||||
#### Method 5 – Using fsck command
|
||||
|
||||
The **fsck** command is used to check the integrity of a filesystem or repair it. You can find the type of a filesystem by passing the partition as an argument like below.
|
||||
```
|
||||
$ fsck -N /dev/sda1
|
||||
fsck from util-linux 2.32
|
||||
[/usr/bin/fsck.ext4 (1) -- /boot] fsck.ext4 /dev/sda1
|
||||
|
||||
```
|
||||
|
||||
For more details, refer man pages.
|
||||
```
|
||||
$ man fsck
|
||||
|
||||
```
|
||||
|
||||
#### Method 6 – Using fstab Command
|
||||
|
||||
**fstab** is a file that contains static information about the filesystems. This file usually contains the mount point, filesystem type and mount options.
|
||||
|
||||
To view the type of a filesystem, simply run:
|
||||
```
|
||||
$ cat /etc/fstab
|
||||
|
||||
```
|
||||
|
||||
![][5]
|
||||
|
||||
For more details, refer man pages.
|
||||
```
|
||||
$ man fstab
|
||||
|
||||
```
|
||||
|
||||
#### Method 7 – Using lsblk command
|
||||
|
||||
The **lsblk** command displays the information about devices.
|
||||
|
||||
To display info about mounted filesystems, simply run:
|
||||
```
|
||||
$ lsblk -f
|
||||
NAME FSTYPE LABEL UUID MOUNTPOINT
|
||||
loop0 squashfs /var/lib/snapd/snap/core/4327
|
||||
sda
|
||||
├─sda1 ext4 83a1dbbf-1e15-4b45-94fe-134d3872af96 /boot
|
||||
├─sda2 ext4 4d25ddb0-5b20-40b4-ae35-ef96376d6594 /
|
||||
└─sda3 swap 1f8f5e2e-7c17-4f35-97e6-8bce7a4849cb [SWAP]
|
||||
sr0
|
||||
|
||||
```
|
||||
|
||||
For more details, refer man pages.
|
||||
```
|
||||
$ man lsblk
|
||||
|
||||
```
|
||||
|
||||
#### Method 8 – Using mount command
|
||||
|
||||
The **mount** command is used to mount a local or remote filesystems in Unix-like systems.
|
||||
|
||||
To find out the type of a filesystem using mount command, do:
|
||||
```
|
||||
$ mount | grep "^/dev"
|
||||
/dev/sda2 on / type ext4 (rw,relatime,commit=360)
|
||||
/dev/sda1 on /boot type ext4 (rw,relatime,commit=360,data=ordered)
|
||||
|
||||
```
|
||||
|
||||
For more details, refer man pages.
|
||||
```
|
||||
$ man mount
|
||||
|
||||
```
|
||||
|
||||
And, that’s all for now folks. You now know 8 different Linux commands to find out the type of a mounted Linux filesystems. If you know any other methods, feel free to let me know in the comment section below. I will check and update this guide accordingly.
|
||||
|
||||
More good stuffs to come. Stay tuned!
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.ostechnix.com/how-to-find-the-mounted-filesystem-type-in-linux/
|
||||
|
||||
作者:[SK][a]
|
||||
选题:[lujun9972](https://github.com/lujun9972)
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.ostechnix.com/author/sk/
|
||||
[1]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[2]:http://www.ostechnix.com/wp-content/uploads/2018/07/findmnt-1.png
|
||||
[3]:http://www.ostechnix.com/wp-content/uploads/2018/07/findmnt-2.png
|
||||
[4]:http://www.ostechnix.com/wp-content/uploads/2018/07/df.png
|
||||
[5]:http://www.ostechnix.com/wp-content/uploads/2018/07/fstab.png
|
@ -1,94 +0,0 @@
|
||||
Translating by jlztan
|
||||
|
||||
Top 10 Raspberry Pi blogs to follow
|
||||
======
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/raspberry-pi-juggle.png?itok=oTgGGSRA)
|
||||
|
||||
There are plenty of great Raspberry Pi fan sites, tutorials, repositories, YouTube channels, and other resources on the web. Here are my top 10 favorite Raspberry Pi blogs, in no particular order.
|
||||
|
||||
### 1. Raspberry Pi Spy
|
||||
|
||||
Raspberry Pi fan Matt Hawkins has been writing a broad range of comprehensive and informative tutorials on his site, Raspberry Pi Spy, since the early days. I have learned a lot directly from this site, and Matt always seems to be the first to cover many topics. I have reached out for help many times in my first three years in the world of hacking and making with Raspberry Pi.
|
||||
|
||||
Fortunately for everyone, this early adopter site is still going strong. I hope to see it live on, giving new community members a helping hand when they need it.
|
||||
|
||||
### 2. Adafruit
|
||||
|
||||
Adafruit is one of the biggest names in hardware hacking. The company makes and sells beautiful hardware and provides excellent tutorials written by staff, community members, and even the wonderful Lady Ada herself.
|
||||
|
||||
As well as being a webshop, Adafruit also run a blog, which is full to the brim of great content from around the world. Check out the Raspberry Pi category, especially at the end of the work week, as [Friday is Pi Day][1] at Adafruit Towers.
|
||||
|
||||
### 3. Recantha's Raspberry Pi Pod
|
||||
|
||||
Mike Horne (Recantha) is a key Pi community member in the UK who runs the [CamJam and Potton Pi & Pint][2] (two Raspberry Jams in Cambridge) and [Pi Wars][3] (an annual Pi robotics competition). He gives advice to others setting up Jams and always has time to help beginners. With his co-organizer Tim Richardson, Horne developed the CamJam Edu Kit (a series of small and affordable kits for beginners to learn physical computing with Python).
|
||||
|
||||
On top of all this, he runs the Pi Pod, a blog full of anything and everything Pi-related from around the world. It's probably the most regularly updated Pi blog on this list, so it's a great way to keep your finger on the pulse of the Pi community.
|
||||
|
||||
### 4. Raspberry Pi blog
|
||||
|
||||
Not forgetting the official [Raspberry Pi Foundation][4], this blog covers a range of content from the Foundation's world of hardware, software, education, community, and charity and youth coding clubs. Big themes on the blog are digital making at home, empowerment through education, as well as official news on hardware releases and software updates.
|
||||
|
||||
The blog has been running [since 2011][5] and provides an [archive][6] of all 1800+ posts since that time. You can also follow [@raspberrypi_otd][7] on Twitter, which is a bot I created in [Python][8] (for an [Opensource.com tutorial][9], of course). The bot tweets links to blog posts from the current day in previous years from the Raspberry Pi blog archive.
|
||||
|
||||
### 5. RasPi.tv
|
||||
|
||||
Another seminal Raspberry Pi community member is Alex Eames, who got on board early on with his blog and YouTube channel, RasPi.tv. The site is packed with high-quality, well-produced video tutorials and written guides covering maker projects for all.
|
||||
|
||||
Alex makes a series of add-on boards and accessories for the Pi as [RasP.iO][10], including a handy GPIO port label, reference rulers, and more. His blog branches out into [Arduino][11], [WEMO][12], and other small boards too.
|
||||
|
||||
### 6. pyimagesearch
|
||||
|
||||
Though not strictly a Raspberry Pi blog (the "py" in the name is for "Python," not "Raspberry Pi"), this site features an extensive [Raspberry Pi category][13]. Adrian Rosebrock earned a PhD studying the fields of computer vision and machine learning. His blog aims to share the machine learning tricks he's picked up while studying and making his own computer vision projects.
|
||||
|
||||
If you want to learn about facial or object recognition using the Pi camera module, this is the place to be. Adrian's knowledge and practical application of deep learning and AI for image recognition is second to none—and he writes up his projects so that anyone can try.
|
||||
|
||||
### 7. Raspberry Pi Roundup
|
||||
|
||||
One of the UK's official Raspberry Pi resellers, The Pi Hut, maintains a blog curating the finds of the week. It's another great resource to keep up with what's on in the Pi world, and worth looking back through past issues.
|
||||
|
||||
### 8. Dave Akerman
|
||||
|
||||
A leading expert in high-altitude ballooning, Dave Akerman shares his knowledge and experience with balloon launches at minimal cost using Raspberry Pi. He publishes writeups of his launches with photos from the stratosphere and offers tips on how to launch a Pi balloon yourself.
|
||||
|
||||
Check out Dave's blogfor amazing photography from near space.
|
||||
|
||||
### 9. Pimoroni
|
||||
|
||||
A world-renowned Raspberry Pi reseller based in Sheffield in the UK, Pimoroni made the famous [Pibow Rainbow case][14] and followed it up with a host of incredible custom add-on boards and accessories.
|
||||
|
||||
Pimoroni's blog is laid out as beautifully as its hardware design and branding, and it provides great content for makers and hobbyists at home. The blog accompanies their entertaining YouTube channel [Bilge Tank][15].
|
||||
|
||||
### 10. Stuff About Code
|
||||
|
||||
Martin O'Hanlon is a Pi community member-turned-Foundation employee who started out hacking Minecraft on the Pi for fun and recently joined the Foundation as a content writer. Luckily, Martin's new job hasn't stopped him from updating his blog and sharing useful tidbits with the world. As well as lots on Minecraft, you'll find stuff on the Python libraries, [Blue Dot][16], and [guizero][17], along with general Raspberry Pi tips.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/18/8/top-10-raspberry-pi-blogs-follow
|
||||
|
||||
作者:[Ben Nuttall][a]
|
||||
选题:[lujun9972](https://github.com/lujun9972)
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://opensource.com/users/bennuttall
|
||||
[1]:https://blog.adafruit.com/category/raspberry-pi/
|
||||
[2]:https://camjam.me/?page_id=753
|
||||
[3]:https://piwars.org/
|
||||
[4]:https://www.raspberrypi-spy.co.uk/
|
||||
[5]:https://www.raspberrypi.org/blog/first-post/
|
||||
[6]:https://www.raspberrypi.org/blog/archive/
|
||||
[7]:https://twitter.com/raspberrypi_otd
|
||||
[8]:https://github.com/bennuttall/rpi-otd-bot/blob/master/src/bot.py
|
||||
[9]:https://opensource.com/article/17/8/raspberry-pi-twitter-bot
|
||||
[10]:https://rasp.io/
|
||||
[11]:https://www.arduino.cc/
|
||||
[12]:http://community.wemo.com/
|
||||
[13]:https://www.pyimagesearch.com/category/raspberry-pi/
|
||||
[14]:https://shop.pimoroni.com/products/pibow-for-raspberry-pi-3-b-plus
|
||||
[15]:https://www.youtube.com/channel/UCuiDNTaTdPTGZZzHm0iriGQ
|
||||
[16]:https://bluedot.readthedocs.io/en/latest/#
|
||||
[17]:https://lawsie.github.io/guizero/
|
@ -1,3 +1,5 @@
|
||||
FSSlc translating
|
||||
|
||||
A Cross-platform High-quality GIF Encoder
|
||||
======
|
||||
|
||||
|
@ -1,546 +0,0 @@
|
||||
[translating by jrg 20181014]
|
||||
|
||||
Using Grails with jQuery and DataTables
|
||||
======
|
||||
|
||||
Learn to build a Grails-based data browser that lets users visualize complex tabular data.
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/data_container_block.png?itok=S8MbXEYw)
|
||||
|
||||
I’m a huge fan of [Grails][1]. Granted, I’m mostly a data person who likes to explore and analyze data using command-line tools. But even data people sometimes need to _look at_ the data, and sometimes using data means having a great data browser. With Grails, [jQuery][2], and the [DataTables jQuery plugin][3], we can make really nice tabular data browsers.
|
||||
|
||||
The [DataTables website][3] offers a lot of decent “recipe-style” documentation that shows how to put together some fine sample applications, and it includes the necessary JavaScript, HTML, and occasional [PHP][4] to accomplish some pretty spiffy stuff. But for those who would rather use Grails as their backend, a bit of interpretation is necessary. Also, the sample application data used is a single flat table of employees of a fictional company, so the complexity of dealing with table relations serves as an exercise for the reader.
|
||||
|
||||
In this article, we’ll fill those two gaps by creating a Grails application with a slightly more complex data structure and a DataTables browser. In doing so, we’ll cover Grails criteria, which are [Groovy][5] -fied Java Hibernate criteria. I’ve put the code for the application on [GitHub][6] , so this article is oriented toward explaining the nuances of the code.
|
||||
|
||||
For prerequisites, you will need Java, Groovy, and Grails environments set up. With Grails, I tend to use a terminal window and [Vim][7], so that’s what’s used here. To get a modern Java, I suggest downloading and installing the [Open Java Development Kit][8] (OpenJDK) provided by your Linux distro (which should be Java 8, 9, 10 or 11; at the time of writing, I’m working with Java 8). From my point of view, the best way to get up-to-date Groovy and Grails is to use [SDKMAN!][9].
|
||||
|
||||
Readers who have never tried Grails will probably need to do some background reading. As a starting point, I recommend [Creating Your First Grails Application][10].
|
||||
|
||||
### Getting the employee browser application
|
||||
|
||||
As mentioned above, I’ve put the source code for this sample employee browser application on [GitHub][6]. For further explanation, the application **embrow** was built using the following commands in a Linux terminal window:
|
||||
|
||||
```
|
||||
cd Projects
|
||||
grails create-app com.nuevaconsulting.embrow
|
||||
```
|
||||
|
||||
The domain classes and unit tests are created as follows:
|
||||
|
||||
```
|
||||
grails create-domain-class com.nuevaconsulting.embrow.Position
|
||||
grails create-domain-class com.nuevaconsulting.embrow.Office
|
||||
grails create-domain-class com.nuevaconsulting.embrow.Employeecd embrowgrails createdomaincom.grails createdomaincom.grails createdomaincom.
|
||||
```
|
||||
|
||||
The domain classes built this way have no attributes, so they must be edited as follows:
|
||||
|
||||
The Position domain class:
|
||||
|
||||
```
|
||||
package com.nuevaconsulting.embrow
|
||||
|
||||
class Position {
|
||||
|
||||
String name
|
||||
int starting
|
||||
|
||||
static constraints = {
|
||||
name nullable: false, blank: false
|
||||
starting nullable: false
|
||||
}
|
||||
}com.Stringint startingstatic constraintsnullableblankstarting nullable
|
||||
```
|
||||
|
||||
The Office domain class:
|
||||
|
||||
```
|
||||
package com.nuevaconsulting.embrow
|
||||
|
||||
class Office {
|
||||
|
||||
String name
|
||||
String address
|
||||
String city
|
||||
String country
|
||||
|
||||
static constraints = {
|
||||
name nullable: false, blank: false
|
||||
address nullable: false, blank: false
|
||||
city nullable: false, blank: false
|
||||
country nullable: false, blank: false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
And the Employee domain class:
|
||||
|
||||
```
|
||||
package com.nuevaconsulting.embrow
|
||||
|
||||
class Employee {
|
||||
|
||||
String surname
|
||||
String givenNames
|
||||
Position position
|
||||
Office office
|
||||
int extension
|
||||
Date hired
|
||||
int salary
|
||||
static constraints = {
|
||||
surname nullable: false, blank: false
|
||||
givenNames nullable: false, blank: false
|
||||
: false
|
||||
office nullable: false
|
||||
extension nullable: false
|
||||
hired nullable: false
|
||||
salary nullable: false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note that whereas the Position and Office domain classes use predefined Groovy types String and int, the Employee domain class defines fields that are of type Position and Office (as well as the predefined Date). This causes the creation of the database table in which instances of Employee are stored to contain references, or foreign keys, to the tables in which instances of Position and Office are stored.
|
||||
|
||||
Now you can generate the controllers, views, and various other test components:
|
||||
|
||||
```
|
||||
-all com.nuevaconsulting.embrow.Position
|
||||
grails generate-all com.nuevaconsulting.embrow.Office
|
||||
grails generate-all com.nuevaconsulting.embrow.Employeegrails generateall com.grails generateall com.grails generateall com.
|
||||
```
|
||||
|
||||
At this point, you have a basic create-read-update-delete (CRUD) application ready to go. I’ve included some base data in the **grails-app/init/com/nuevaconsulting/BootStrap.groovy** to populate the tables.
|
||||
|
||||
If you run the application with the command:
|
||||
|
||||
```
|
||||
grails run-app
|
||||
```
|
||||
|
||||
you will see the following screen in the browser at **<http://localhost:8080/:>**
|
||||
|
||||
![Embrow home screen][12]
|
||||
|
||||
The Embrow application home screen
|
||||
|
||||
Clicking on the link for the OfficeController gives you a screen that looks like this:
|
||||
|
||||
![Office list][14]
|
||||
|
||||
The office list
|
||||
|
||||
Note that this list is generated by the **OfficeController index** method and displayed by the view `office/index.gsp`.
|
||||
|
||||
Similarly, clicking on the **EmployeeController** gives a screen that looks like this:
|
||||
|
||||
![Employee controller][16]
|
||||
|
||||
The employee controller
|
||||
|
||||
Ok, that’s pretty ugly—what’s with the Position and Office links?
|
||||
|
||||
Well, the views generated by the `generate-all` commands above create an **index.gsp** file that uses the Grails <f:table/> tag that by default shows the class name ( **com.nuevaconsulting.embrow.Position** ) and the persistent instance identifier ( **30** ). This behavior can be customized to yield something better looking, and there is some pretty neat stuff with the autogenerated links, the autogenerated pagination, and the autogenerated sortable columns.
|
||||
|
||||
But even when it's fully cleaned up, this employee browser offers limited functionality. For example, what if you want to find all employees whose position includes the text “dev”? What if you want to combine columns for sorting so that the primary sort key is a surname and the secondary sort key is an office name? Or what if you want to export a sorted subset to a spreadsheet or PDF to email to someone who doesn’t have access to the browser?
|
||||
|
||||
The jQuery DataTables plugin provides this kind of extra functionality and allows you to create a full-fledged tabular data browser.
|
||||
|
||||
### Creating the employee browser view and controller methods
|
||||
|
||||
In order to create an employee browser based on jQuery DataTables, you must complete two tasks:
|
||||
|
||||
1. Create a Grails view that incorporates the HTML and JavaScript required to enable the DataTables
|
||||
|
||||
2. Add a method to the Grails controller to handle the new view
|
||||
|
||||
|
||||
|
||||
|
||||
#### The employee browser view
|
||||
|
||||
In the directory **embrow/grails-app/views/employee** , start by making a copy of the **index.gsp** file, calling it **browser.gsp** :
|
||||
|
||||
```
|
||||
cd Projects
|
||||
cd embrow/grails-app/views/employee
|
||||
cp gsp browser.gsp
|
||||
```
|
||||
|
||||
At this point, you want to customize the new **browser.gsp** file to add the relevant jQuery DataTables code.
|
||||
|
||||
As a rule, I like to grab my JavaScript and CSS from a content provider when feasible; to do so in this case, after the line:
|
||||
|
||||
```
|
||||
<title><g:message code="default.list.label" args="[entityName]" /></title>
|
||||
```
|
||||
|
||||
insert the following lines:
|
||||
|
||||
```
|
||||
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.css">
|
||||
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/scroller/1.4.4/css/scroller.dataTables.min.css">
|
||||
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/scroller/1.4.4/js/dataTables.scroller.min.js"></script>
|
||||
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/buttons/1.5.1/js/dataTables.buttons.min.js"></script>
|
||||
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/buttons/1.5.1/js/buttons.flash.min.js"></script>
|
||||
<script type="text/javascript" charset="utf8" src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
|
||||
<script type="text/javascript" charset="utf8" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.32/pdfmake.min.js"></script>
|
||||
<script type="text/javascript" charset="utf8" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.32/vfs_fonts.js"></script>
|
||||
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/buttons/1.5.1/js/buttons.html5.min.js"></script>
|
||||
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/buttons/1.5.1/js/buttons.print.min.js "></script>
|
||||
```
|
||||
|
||||
Next, remove the code that provided the data pagination in **index.gsp** :
|
||||
|
||||
```
|
||||
<div id="list-employee" class="content scaffold-list" role="main">
|
||||
<h1><g:message code="default.list.label" args="[entityName]" /></h1>
|
||||
<g:if test="${flash.message}">
|
||||
<div class="message" role="status">${flash.message}</div>
|
||||
</g:if>
|
||||
<f:table collection="${employeeList}" />
|
||||
|
||||
<div class="pagination">
|
||||
<g:paginate total="${employeeCount ?: 0}" />
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
and insert the code that materializes the jQuery DataTables.
|
||||
|
||||
The first part to insert is the HTML that creates the basic tabular structure of the browser. For the application where DataTables talks to a database backend, provide only the table headers and footers; the DataTables JavaScript takes care of the table contents.
|
||||
|
||||
```
|
||||
<div id="employee-browser" class="content" role="main">
|
||||
<h1>Employee Browser</h1>
|
||||
<table id="employee_dt" class="display compact" style="width:99%;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Surname</th>
|
||||
<th>Given name(s)</th>
|
||||
<th>Position</th>
|
||||
<th>Office</th>
|
||||
<th>Extension</th>
|
||||
<th>Hired</th>
|
||||
<th>Salary</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th>Surname</th>
|
||||
<th>Given name(s)</th>
|
||||
<th>Position</th>
|
||||
<th>Office</th>
|
||||
<th>Extension</th>
|
||||
<th>Hired</th>
|
||||
<th>Salary</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
```
|
||||
|
||||
Next, insert a JavaScript block, which serves three primary functions: It sets the size of the text boxes shown in the footer for column filtering, it establishes the DataTables table model, and it creates a handler to do the column filtering.
|
||||
|
||||
```
|
||||
<g:javascript>
|
||||
$('#employee_dt tfoot th').each( function() {javascript
|
||||
```
|
||||
|
||||
The code below handles sizing the filter boxes at the bottoms of the table columns:
|
||||
|
||||
```
|
||||
var title = $(this).text();
|
||||
if (title == 'Extension' || title == 'Hired')
|
||||
$(this).html('<input type="text" size="5" placeholder="' + title + '?" />');
|
||||
else
|
||||
$(this).html('<input type="text" size="15" placeholder="' + title + '?" />');
|
||||
});titletitletitletitletitle
|
||||
```
|
||||
|
||||
Next, define the table model. This is where all the table options are provided, including the scrolling, rather than paginated, nature of the interface, the cryptic decorations to be provided according to the dom string, the ability to export data to CSV and other formats, as well as where the Ajax connection to the server is established. Note that the URL is created with a Groovy GString call to the Grails **createLink()** method, referring to the **browserLister** action in the **EmployeeController**. Also of interest is the definition of the columns of the table. This information is sent across to the back end, which queries the database and returns the appropriate records.
|
||||
|
||||
```
|
||||
var table = $('#employee_dt').DataTable( {
|
||||
"scrollY": 500,
|
||||
"deferRender": true,
|
||||
"scroller": true,
|
||||
"dom": "Brtip",
|
||||
"buttons": [ 'copy', 'csv', 'excel', 'pdf', 'print' ],
|
||||
"processing": true,
|
||||
"serverSide": true,
|
||||
"ajax": {
|
||||
"url": "${createLink(controller: 'employee', action: 'browserLister')}",
|
||||
"type": "POST",
|
||||
},
|
||||
"columns": [
|
||||
{ "data": "surname" },
|
||||
{ "data": "givenNames" },
|
||||
{ "data": "position" },
|
||||
{ "data": "office" },
|
||||
{ "data": "extension" },
|
||||
{ "data": "hired" },
|
||||
{ "data": "salary" }
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
Finally, monitor the filter columns for changes and use them to apply the filter(s).
|
||||
|
||||
```
|
||||
table.columns().every(function() {
|
||||
var that = this;
|
||||
$('input', this.footer()).on('keyup change', function(e) {
|
||||
if (that.search() != this.value && 8 < e.keyCode && e.keyCode < 32)
|
||||
that.search(this.value).draw();
|
||||
});
|
||||
```
|
||||
|
||||
And that’s it for the JavaScript. This completes the changes to the view code.
|
||||
|
||||
```
|
||||
});
|
||||
</g:javascript>
|
||||
```
|
||||
|
||||
Here’s a screenshot of the UI this view creates:
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/screen_4.png)
|
||||
|
||||
Here’s another screenshot showing the filtering and multi-column sorting at work (looking for employees whose positions include the characters “dev”, ordering first by office, then by surname):
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/screen_5.png)
|
||||
|
||||
Here’s another screenshot, showing what happens when you click on the CSV button:
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/screen6.png)
|
||||
|
||||
And finally, here’s a screenshot showing the CSV data opened in LibreOffice:
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/screen7.png)
|
||||
|
||||
Ok, so the view part looked pretty straightforward; therefore, the controller action must do all the heavy lifting, right? Let’s see…
|
||||
|
||||
#### The employee controller browserLister action
|
||||
|
||||
Recall that we saw this string
|
||||
|
||||
```
|
||||
"${createLink(controller: 'employee', action: 'browserLister')}"
|
||||
```
|
||||
|
||||
as the URL used for the Ajax calls from the DataTables table model. [createLink() is the method][17] behind a Grails tag that is used to dynamically generate a link as the HTML is preprocessed on the Grails server. This ends up generating a link to the **EmployeeController** , located in
|
||||
|
||||
```
|
||||
embrow/grails-app/controllers/com/nuevaconsulting/embrow/EmployeeController.groovy
|
||||
```
|
||||
|
||||
and specifically to the controller method **browserLister()**. I’ve left some print statements in the code so that the intermediate results can be seen in the terminal window where the application is running.
|
||||
|
||||
```
|
||||
def browserLister() {
|
||||
// Applies filters and sorting to return a list of desired employees
|
||||
```
|
||||
|
||||
First, print out the parameters passed to **browserLister()**. I usually start building controller methods with this code so that I’m completely clear on what my controller is receiving.
|
||||
|
||||
```
|
||||
println "employee browserLister params $params"
|
||||
println()
|
||||
```
|
||||
|
||||
Next, process those parameters to put them in a more usable shape. First, the jQuery DataTables parameters, a Groovy map called **jqdtParams** :
|
||||
|
||||
```
|
||||
def jqdtParams = [:]
|
||||
params.each { key, value ->
|
||||
def keyFields = key.replace(']','').split(/\[/)
|
||||
def table = jqdtParams
|
||||
for (int f = 0; f < keyFields.size() - 1; f++) {
|
||||
def keyField = keyFields[f]
|
||||
if (!table.containsKey(keyField))
|
||||
table[keyField] = [:]
|
||||
table = table[keyField]
|
||||
}
|
||||
table[keyFields[-1]] = value
|
||||
}
|
||||
println "employee dataTableParams $jqdtParams"
|
||||
println()
|
||||
```
|
||||
|
||||
Next, the column data, a Groovy map called **columnMap** :
|
||||
|
||||
```
|
||||
def columnMap = jqdtParams.columns.collectEntries { k, v ->
|
||||
def whereTerm = null
|
||||
switch (v.data) {
|
||||
case 'extension':
|
||||
case 'hired':
|
||||
case 'salary':
|
||||
if (v.search.value ==~ /\d+(,\d+)*/)
|
||||
whereTerm = v.search.value.split(',').collect { it as Integer }
|
||||
break
|
||||
default:
|
||||
if (v.search.value ==~ /[A-Za-z0-9 ]+/)
|
||||
whereTerm = "%${v.search.value}%" as String
|
||||
break
|
||||
}
|
||||
[(v.data): [where: whereTerm]]
|
||||
}
|
||||
println "employee columnMap $columnMap"
|
||||
println()
|
||||
```
|
||||
|
||||
Next, a list of all column names, retrieved from **columnMap** , and a corresponding list of how those columns should be ordered in the view, Groovy lists called **allColumnList** and **orderList** , respectively:
|
||||
|
||||
```
|
||||
def allColumnList = columnMap.keySet() as List
|
||||
println "employee allColumnList $allColumnList"
|
||||
def orderList = jqdtParams.order.collect { k, v -> [allColumnList[v.column as Integer], v.dir] }
|
||||
println "employee orderList $orderList"
|
||||
```
|
||||
|
||||
We’re going to use Grails’ implementation of Hibernate criteria to actually carry out the selection of elements to be displayed as well as their ordering and pagination. Criteria requires a filter closure; in most examples, this is given as part of the creation of the criteria instance itself, but here we define the filter closure beforehand. Note in this case the relatively complex interpretation of the “date hired” filter, which is treated as a year and applied to establish date ranges, and the use of **createAlias** to allow us to reach into related classes Position and Office:
|
||||
|
||||
```
|
||||
def filterer = {
|
||||
createAlias 'position', 'p'
|
||||
createAlias 'office', 'o'
|
||||
|
||||
if (columnMap.surname.where) ilike 'surname', columnMap.surname.where
|
||||
if (columnMap.givenNames.where) ilike 'givenNames', columnMap.givenNames.where
|
||||
if (columnMap.position.where) ilike 'p.name', columnMap.position.where
|
||||
if (columnMap.office.where) ilike 'o.name', columnMap.office.where
|
||||
if (columnMap.extension.where) inList 'extension', columnMap.extension.where
|
||||
if (columnMap.salary.where) inList 'salary', columnMap.salary.where
|
||||
if (columnMap.hired.where) {
|
||||
if (columnMap.hired.where.size() > 1) {
|
||||
or {
|
||||
columnMap.hired.where.each {
|
||||
between 'hired', Date.parse('yyyy/MM/dd',"${it}/01/01" as String),
|
||||
Date.parse('yyyy/MM/dd',"${it}/12/31" as String)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
between 'hired', Date.parse('yyyy/MM/dd',"${columnMap.hired.where[0]}/01/01" as String),
|
||||
Date.parse('yyyy/MM/dd',"${columnMap.hired.where[0]}/12/31" as String)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
At this point, it’s time to apply the foregoing. The first step is to get a total count of all the Employee instances, required by the pagination code:
|
||||
|
||||
```
|
||||
def recordsTotal = Employee.count()
|
||||
println "employee recordsTotal $recordsTotal"
|
||||
```
|
||||
|
||||
Next, apply the filter to the Employee instances to get the count of filtered results, which will always be less than or equal to the total number (again, this is for the pagination code):
|
||||
|
||||
```
|
||||
def c = Employee.createCriteria()
|
||||
def recordsFiltered = c.count {
|
||||
filterer.delegate = delegate
|
||||
filterer()
|
||||
}
|
||||
println "employee recordsFiltered $recordsFiltered"
|
||||
|
||||
```
|
||||
|
||||
Once you have those two counts, you can get the actual filtered instances using the pagination and ordering information as well.
|
||||
|
||||
```
|
||||
def orderer = Employee.withCriteria {
|
||||
filterer.delegate = delegate
|
||||
filterer()
|
||||
orderList.each { oi ->
|
||||
switch (oi[0]) {
|
||||
case 'surname': order 'surname', oi[1]; break
|
||||
case 'givenNames': order 'givenNames', oi[1]; break
|
||||
case 'position': order 'p.name', oi[1]; break
|
||||
case 'office': order 'o.name', oi[1]; break
|
||||
case 'extension': order 'extension', oi[1]; break
|
||||
case 'hired': order 'hired', oi[1]; break
|
||||
case 'salary': order 'salary', oi[1]; break
|
||||
}
|
||||
}
|
||||
maxResults (jqdtParams.length as Integer)
|
||||
firstResult (jqdtParams.start as Integer)
|
||||
}
|
||||
```
|
||||
|
||||
To be completely clear, the pagination code in JTables manages three counts: the total number of records in the data set, the number resulting after the filters are applied, and the number to be displayed on the page (whether the display is scrolling or paginated). The ordering is applied to all the filtered records and the pagination is applied to chunks of those filtered records for display purposes.
|
||||
|
||||
Next, process the results returned by the orderer, creating links to the Employee, Position, and Office instance in each row so the user can click on these links to get all the detail on the relevant instance:
|
||||
|
||||
```
|
||||
def dollarFormatter = new DecimalFormat('$##,###.##')
|
||||
def employees = orderer.collect { employee ->
|
||||
['surname': "<a href='${createLink(controller: 'employee', action: 'show', id: employee.id)}'>${employee.surname}</a>",
|
||||
'givenNames': employee.givenNames,
|
||||
'position': "<a href='${createLink(controller: 'position', action: 'show', id: employee.position?.id)}'>${employee.position?.name}</a>",
|
||||
'office': "<a href='${createLink(controller: 'office', action: 'show', id: employee.office?.id)}'>${employee.office?.name}</a>",
|
||||
'extension': employee.extension,
|
||||
'hired': employee.hired.format('yyyy/MM/dd'),
|
||||
'salary': dollarFormatter.format(employee.salary)]
|
||||
}
|
||||
```
|
||||
|
||||
And finally, create the result you want to return and give it back as JSON, which is what jQuery DataTables requires.
|
||||
|
||||
```
|
||||
def result = [draw: jqdtParams.draw, recordsTotal: recordsTotal, recordsFiltered: recordsFiltered, data: employees]
|
||||
render(result as JSON)
|
||||
}
|
||||
```
|
||||
|
||||
That’s it.
|
||||
|
||||
If you’re familiar with Grails, this probably seems like more work than you might have originally thought, but there’s no rocket science here, just a lot of moving parts. However, if you haven’t had much exposure to Grails (or to Groovy), there’s a lot of new stuff to understand—closures, delegates, and builders, among other things.
|
||||
|
||||
In that case, where to start? The best place is to learn about Groovy itself, especially [Groovy closures][18] and [Groovy delegates and builders][19]. Then go back to the reading suggested above on Grails and Hibernate criteria queries.
|
||||
|
||||
### Conclusions
|
||||
|
||||
jQuery DataTables make awesome tabular data browsers for Grails. Coding the view isn’t too tricky, but the PHP examples provided in the DataTables documentation take you only so far. In particular, they aren’t written with Grails programmers in mind, nor do they explore the finer details of using elements that are references to other classes (essentially lookup tables).
|
||||
|
||||
I’ve used this approach to make a couple of data browsers that allow the user to select which columns to view and accumulate record counts, or just to browse the data. The performance is good even in million-row tables on a relatively modest VPS.
|
||||
|
||||
One caveat: I have stumbled upon some problems with the various Hibernate criteria mechanisms exposed in Grails (see my other GitHub repositories), so care and experimentation is required. If all else fails, the alternative approach is to build SQL strings on the fly and execute them instead. As of this writing, I prefer to work with Grails criteria, unless I get into messy subqueries, but that may just reflect my relative lack of experience with subqueries in Hibernate.
|
||||
|
||||
I hope you Grails programmers out there find this interesting. Please feel free to leave comments or suggestions below.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/18/9/using-grails-jquery-and-datatables
|
||||
|
||||
作者:[Chris Hermansen][a]
|
||||
选题:[lujun9972](https://github.com/lujun9972)
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/clhermansen
|
||||
[1]: https://grails.org/
|
||||
[2]: https://jquery.com/
|
||||
[3]: https://datatables.net/
|
||||
[4]: http://php.net/
|
||||
[5]: http://groovy-lang.org/
|
||||
[6]: https://github.com/monetschemist/grails-datatables
|
||||
[7]: https://www.vim.org/
|
||||
[8]: http://openjdk.java.net/
|
||||
[9]: http://sdkman.io/
|
||||
[10]: http://guides.grails.org/creating-your-first-grails-app/guide/index.html
|
||||
[11]: https://opensource.com/file/410061
|
||||
[12]: https://opensource.com/sites/default/files/uploads/screen_1.png (Embrow home screen)
|
||||
[13]: https://opensource.com/file/410066
|
||||
[14]: https://opensource.com/sites/default/files/uploads/screen_2.png (Office list screenshot)
|
||||
[15]: https://opensource.com/file/410071
|
||||
[16]: https://opensource.com/sites/default/files/uploads/screen3.png (Employee controller screenshot)
|
||||
[17]: https://gsp.grails.org/latest/ref/Tags/createLink.html
|
||||
[18]: http://groovy-lang.org/closures.html
|
||||
[19]: http://groovy-lang.org/dsls.html
|
@ -1,78 +0,0 @@
|
||||
fuowang 翻译中
|
||||
|
||||
4 open source invoicing tools for small businesses
|
||||
======
|
||||
Manage your billing and get paid with easy-to-use, web-based invoicing software.
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BUS_lovemoneyglory2.png?itok=AvneLxFp)
|
||||
|
||||
No matter what your reasons for starting a small business, the key to keeping that business going is getting paid. Getting paid usually means sending a client an invoice.
|
||||
|
||||
It's easy enough to whip up an invoice using LibreOffice Writer or LibreOffice Calc, but sometimes you need a bit more. A more professional look. A way of keeping track of your invoices. Reminders about when to follow up on the invoices you've sent.
|
||||
|
||||
There's a wide range of commercial and closed-source invoicing tools out there. But the offerings on the open source side of the fence are just as good, and maybe even more flexible, than their closed source counterparts.
|
||||
|
||||
Let's take a look at four web-based open source invoicing tools that are great choices for freelancers and small businesses on a tight budget. I reviewed two of them in 2014, in an [earlier version][1] of this article. These four picks are easy to use and you can use them on just about any device.
|
||||
|
||||
### Invoice Ninja
|
||||
|
||||
I've never been a fan of the term ninja. Despite that, I like [Invoice Ninja][2]. A lot. It melds a simple interface with a set of features that let you create, manage, and send invoices to clients and customers.
|
||||
|
||||
You can easily configure multiple clients, track payments and outstanding invoices, generate quotes, and email invoices. What sets Invoice Ninja apart from its competitors is its [integration with][3] over 40 online popular payment gateways, including PayPal, Stripe, WePay, and Apple Pay.
|
||||
|
||||
[Download][4] a version that you can install on your own server or get an account with the [hosted version][5] of Invoice Ninja. There's a free version and a paid tier that will set you back US$ 8 a month.
|
||||
|
||||
### InvoicePlane
|
||||
|
||||
Once upon a time, there was a nifty open source invoicing tool called FusionInvoice. One day, its creators took the latest version of the code proprietary. That didn't end happily, as FusionInvoice's doors were shut for good in 2018. But that wasn't the end of the application. An old version of the code stayed open source and morphed into [InvoicePlane][6], which packs all of FusionInvoice's goodness.
|
||||
|
||||
Creating an invoice takes just a couple of clicks. You can make them as minimal or detailed as you need. When you're ready, you can email your invoices or output them as PDFs. You can also create recurring invoices for clients or customers you regularly bill.
|
||||
|
||||
InvoicePlane does more than generate and track invoices. You can also create quotes for jobs or goods, track products you sell, view and enter payments, and run reports on your invoices.
|
||||
|
||||
[Grab the code][7] and install it on your web server. Or, if you're not quite ready to do that, [take the demo][8] for a spin.
|
||||
|
||||
### OpenSourceBilling
|
||||
|
||||
Described by its developer as "beautifully simple billing software," [OpenSourceBilling][9] lives up to the description. It has one of the cleanest interfaces I've seen, which makes configuring and using the tool a breeze.
|
||||
|
||||
OpenSourceBilling stands out because of its dashboard, which tracks your current and past invoices, as well as any outstanding amounts. Your information is broken up into graphs and tables, which makes it easy to follow.
|
||||
|
||||
You do much of the configuration on the invoice itself. You can add items, tax rates, clients, and even payment terms with a click and a few keystrokes. OpenSourceBilling saves that information across all of your invoices, both new and old.
|
||||
|
||||
As with some of the other tools we've looked at, OpenSourceBilling has a [demo][10] you can try.
|
||||
|
||||
### BambooInvoice
|
||||
|
||||
When I was a full-time freelance writer and consultant, I used [BambooInvoice][11] to bill my clients. When its original developer stopped working on the software, I was a bit disappointed. But BambooInvoice is back, and it's as good as ever.
|
||||
|
||||
What attracted me to BambooInvoice is its simplicity. It does one thing and does it well. You can create and edit invoices, and BambooInvoice keeps track of them by client and by the invoice numbers you assign to them. It also lets you know which invoices are open or overdue. You can email the invoices from within the application or generate PDFs. You can also run reports to keep tabs on your income.
|
||||
|
||||
To [install][12] and use BambooInvoice, you'll need a web server running PHP 5 or newer as well as a MySQL database. Chances are you already have access to one, so you're good to go.
|
||||
|
||||
Do you have a favorite open source invoicing tool? Feel free to share it by leaving a comment.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/18/10/open-source-invoicing-tools
|
||||
|
||||
作者:[Scott Nesbitt][a]
|
||||
选题:[lujun9972](https://github.com/lujun9972)
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/scottnesbitt
|
||||
[1]: https://opensource.com/business/14/9/4-open-source-invoice-tools
|
||||
[2]: https://www.invoiceninja.org/
|
||||
[3]: https://www.invoiceninja.com/integrations/
|
||||
[4]: https://github.com/invoiceninja/invoiceninja
|
||||
[5]: https://www.invoiceninja.com/invoicing-pricing-plans/
|
||||
[6]: https://invoiceplane.com/
|
||||
[7]: https://wiki.invoiceplane.com/en/1.5/getting-started/installation
|
||||
[8]: https://demo.invoiceplane.com/
|
||||
[9]: http://www.opensourcebilling.org/
|
||||
[10]: http://demo.opensourcebilling.org/
|
||||
[11]: https://www.bambooinvoice.net/
|
||||
[12]: https://sourceforge.net/projects/bambooinvoice/
|
@ -1,3 +1,4 @@
|
||||
translating by leemeans
|
||||
Exploring the Linux kernel: The secrets of Kconfig/kbuild
|
||||
======
|
||||
Dive into understanding how the Linux config/build system works.
|
||||
|
@ -0,0 +1,251 @@
|
||||
2017 年必备的 24 个 Linux 应用程序
|
||||
======
|
||||
前情提要:Linux 上必备的应用程序是什么呢?这个答案具有主观性并取决于你使用 Linux 桌面的目的是什么。但确实存在一些必备的并且大部分 Linux 用户都会安装的应用程序。接下来我们会列举出那些在所有 Linux 发行版上你都会安装的最优秀的 Linux 应用程序。
|
||||
|
||||
在 Linux 的世界中,所有东西都由你选择。听说你要选择一个发行版?你能找到一大把。你想要找到一个称心的音乐播放器?同样会有许多选择。
|
||||
|
||||
但他们并非全部遵循相同的设计哲学——其中一些可能追求极致轻量化而另一些会提供数不清的特性。因此想要找到正中需求的应用程序会成为相当令人头疼的繁重任务。那就让我们来缓解你的头疼吧。
|
||||
|
||||
### 对于 Linux 用户来说最优秀的自由软件
|
||||
|
||||
接下来我将罗列一系列在不同应用场景下我偏爱的必备 Linux 自由软件。当然此处我并非在说它们是最好的,但确实是在特定类别下我尝试的一系列软件中最喜欢的。也同样欢迎你在评论区介绍你最喜欢的应用程序。
|
||||
|
||||
同时我们也制作了关于此次应用清单的视频。在油管(译者注:YouTube)上订阅我们的频道获取更多的 Linux 视频。
|
||||
|
||||
### 网页浏览器
|
||||
|
||||
![网页浏览器](https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Web-Browser-1024x512.jpg)
|
||||
[Save][1]网页浏览器
|
||||
|
||||
#### [Google Chrome][12]
|
||||
|
||||
Google Chrome 是一个强大并且功能完善的浏览器解决方案,它拥有完美的同步功能以及丰富的扩展。如果你喜欢 Google 的生态系统那么 Google Chrome 毫无疑问会是你的菜。如果你想要更加开源的解决方案,你可以尝试 [Chromium][13],它是 Google Chrome 的上游项目。
|
||||
|
||||
#### [Firefox][14]
|
||||
|
||||
如果你不是 Google Chrome 的粉丝,你可以尝试 Firefox。它一直以来都是一个非常稳定并且健壮的网页浏览器。
|
||||
|
||||
#### [Vivaldi][15]
|
||||
|
||||
当然,如果你想要尝试点不同的新东西,你可以尝试 Vivaldi。Vivaldi 是一个完全重新设计的网页浏览器,它由 Opera 浏览器项目的前成员基于 Chromium 项目创建。Vivaldi 轻量并且可定制,虽然它还非常年轻并且在某些特性上仍不完善,但它仍能让你眼前一亮并且优雅地工作。
|
||||
|
||||
[推荐阅读[回顾] Otter 浏览器为 Opera 爱好者带来了希望][40]
|
||||
|
||||
### 下载管理器
|
||||
|
||||
![下载管理器](https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Download-Manager-1024x512.jpg)
|
||||
[Save][2]下载管理器
|
||||
|
||||
#### [uGet][16]
|
||||
|
||||
uGet 是我遇到过最棒的下载管理器,它是开源的并且能满足所有你对于一款下载管理器的期许。uGet 提供一系列高级设置便于管理下载。你能够管理下载队列并且断点续传,针对大文件使用多连接下载,根据不同列表将文件下载至不同路径,等等。
|
||||
|
||||
#### [XDM][17]
|
||||
|
||||
Xtreme 下载管理器(XDM)是一个 Java 开发的强大并且开源的下载工具。它拥有下载管理器的所有基本特性,包括视频抓取、智能计划任务以及浏览器集成。
|
||||
|
||||
[推荐阅读 Linux 下最好的 4 个下载管理器][41]
|
||||
|
||||
### BitTorrent 客户端
|
||||
|
||||
![BitTorrent 客户端](https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-BitTorrent-Client-1024x512.jpg)
|
||||
[Save][3]BitTorrent 客户端
|
||||
|
||||
#### [Deluge][18]
|
||||
|
||||
Deluge 是一个拥有漂亮用户界面的开源 BitTorrent 客户端。如果你习惯在 Windows 上使用 uTorrent,那么 Deluge 的界面会让你倍感亲切。它拥有丰富的设置项和针对不同任务的插件支持。
|
||||
|
||||
#### [Transmission][19]
|
||||
|
||||
Transmission 力求精简,它是用户界面最精简的 BitTorrent 客户端之一。Transmission 是许多 Linux 发行版的预装软件。
|
||||
|
||||
[推荐阅读 Ubuntu Linux 上前 5 名的 Torrent 客户端][42]
|
||||
|
||||
### 云存储
|
||||
|
||||
![云存储](https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Cloud-Storage-1024x512.jpg)
|
||||
[Save][4]云存储
|
||||
|
||||
#### [Dropbox][20]
|
||||
|
||||
Dropbox 是目前最流行的云存储服务之一,它为新用户提供了 2GB 的免费存储空间,以及一个健壮并且易于使用的 Linux 客户端。
|
||||
|
||||
#### [MEGA][21]
|
||||
|
||||
MEGA 提供了 50GB 的免费存储,但这还并不是它最大的优点,MEGA 还为你的文件提供了端到端的加密支持。MEGA 提供一个名为 MEGAsync 的 Linux 客户端。
|
||||
|
||||
[推荐阅读 2017 年 Linux 上最优秀的免费云服务][43]
|
||||
|
||||
### 通讯工具
|
||||
|
||||
![通讯工具](https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Communication-1024x512.jpg)
|
||||
[Save][5]通讯工具
|
||||
|
||||
#### [Pidgin][22]
|
||||
|
||||
Pidgin 是一款开源的即时通讯工具,它支持许多聊天平台,包括 Google Talk、Yahoo 甚至 IRC。Pidgin 可通过第三方插件进行扩展,能提供许多附加功能。
|
||||
|
||||
你也可以使用 [Franz][23] 或 [Rambox][24] 来在一个应用中使用多个通讯服务。
|
||||
|
||||
#### [Skype][25]
|
||||
|
||||
我们都知道 Skype 是最流行的视频聊天平台之一,最近它[发布了全新的 Linux 桌面客户端][26]。
|
||||
|
||||
[推荐阅读 2017 年 Linux 平台上最优秀的 6 款消息应用][44]
|
||||
|
||||
### 办公套件
|
||||
|
||||
![办公套件](https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Office-Suite-1024x512.jpg)
|
||||
[Save][6]办公套件
|
||||
|
||||
#### [LibreOffice][27]
|
||||
|
||||
LibreOffice 是 Linux 平台上开发最为活跃的开源办公套件,主要包括 Writer、Calc、Impress、Draw、Math、Base 六个主要模块,并且每个模块都提供广泛的文件格式支持。同时 LibreOffice 也支持第三方的扩展,以上优势使它成为许多 Linux 发行版的默认办公套件。
|
||||
|
||||
#### [WPS Office][28]
|
||||
|
||||
如果你想要尝试除 LibreOffice 以外的办公套件,WPS Office 值得一试。WPS Office 套件包括了写作、演示和数据表格支持。
|
||||
|
||||
[推荐阅读 Linux 平台 6 款最优秀的 Microsoft Office 替代品][45]
|
||||
|
||||
### 音乐播放器
|
||||
|
||||
![音乐播放器](https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Music-Player-1024x512.jpg)
|
||||
[Save][7]音乐播放器
|
||||
|
||||
#### [Lollypop][29]
|
||||
|
||||
Lollypop 是一款相对较新的开源音乐播放器,拥有漂亮又不失简洁的用户界面。它提供优秀的音乐管理、歌曲推荐、在线广播和派对模式支持。虽然它是一款不具有太多特性的简洁音乐播放器,但仍值得我们去尝试。
|
||||
|
||||
#### [Rhythmbox][30]
|
||||
|
||||
Rhythmbox 是一款主要为 GNOME 桌面环境开发的音乐播放器,当然它也可以在其他桌面环境运行。它能完成所有作为一款音乐播放器的基础功能,包括 CD 抓取和烧制、乱序播放,等等。它也提供了 iPod 支持。
|
||||
|
||||
#### [cmus][31]
|
||||
|
||||
如果你想要最轻量,并且喜欢命令行的话,cmus 适合你。个人来讲,我是它的粉丝用户。cmus 是一款类 Unix 平台上,小巧、快速并且强大的命令音乐播放器。它包含所有基础的音乐播放器特性,并且你能够通过扩展和脚本来增强它的功能。
|
||||
|
||||
[推荐阅读 如何在 Ubuntu 14.04 和 Linux Mint 17 上安装 Tomahawk 播放器][46]
|
||||
|
||||
### 视频播放器
|
||||
|
||||
![视频播放器](https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Video-Player-1024x512.jpg)
|
||||
[Save][8]视频播放器
|
||||
|
||||
#### [VLC][32]
|
||||
|
||||
VLC 是一款简洁、快速、轻量并且非常强大的开源媒体播放器,它能够直接播放几乎所有格式的媒体文件,同时也能够播放在线的流媒体。它也能够安装一些时髦的扩展来完成不同的任务,比如直接在播放器内下载字幕。
|
||||
|
||||
#### [Kodi][33]
|
||||
|
||||
Kodi 是一款成熟并且开源的媒体中心,在它的用户群中非常受欢迎。它能够处理来自本地或者网络媒体存储的视频、音乐、图片、播客甚至游戏,更强大的是你还能用它来录制电视节目。Kodi 可由附加组件和皮肤进行定制。
|
||||
|
||||
[推荐阅读 Linux 平台上的 4 款格式工厂替代品][47]
|
||||
|
||||
### 照片编辑器
|
||||
|
||||
![照片编辑器](https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Photo-Editor-1024x512.jpg)
|
||||
[Save][9]照片编辑器
|
||||
|
||||
#### [GIMP][34]
|
||||
|
||||
GIMP 是 Linux 平台上 Photoshop 的替代品,它是一款开源、全功能并且专业的照片编辑软件。它打包了各式各样的工具用来编辑图片,更强大的是,它包含丰富的自定义设置以及第三方插件来增强体验。
|
||||
|
||||
#### [Krita][35]
|
||||
|
||||
Krita 主要是作为一款绘图工具,但也可以作为照片编辑软件。它是开源的并且打包了非常多复杂的高级工具。
|
||||
|
||||
[推荐阅读 Linux 平台最好的照片应用][48]
|
||||
|
||||
### 文字编辑器
|
||||
|
||||
每个 Linux 发行版都拥有自己的文字编缉器解决方案,当然大体上它们都非常简洁并且没有太多功能。但是也有一些文字编辑器具有更强大的功能。
|
||||
|
||||
![文字编辑器](https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Text-Editor-1024x512.jpg)
|
||||
[Save][10]文字编辑器
|
||||
|
||||
#### [Atom][36]
|
||||
|
||||
Atom 是由 GitHub 开发的一款现代高度可配置的文字编辑器,它是完全开源的并且能够提供所有你能想到的文字编辑器功能。你可以开箱即用,也可以将其配置成你想要的样子。并且你可以从它的社区安装大量的扩展和主题。
|
||||
|
||||
#### [Sublime Text][37]
|
||||
|
||||
Sublime Text 是最受欢迎的文字编辑器之一,虽然它并不是免费的,但你可以无限地试用该款软件。Sublime Text 是一款特性丰富并且高度模块化的软件,当然它也提供插件和主题支持。
|
||||
|
||||
[推荐阅读 Linux 平台最优秀的 4 款现代开源代码编辑器][49]
|
||||
|
||||
### 启动器
|
||||
|
||||
![启动器](https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Launcher-1024x512.jpg)
|
||||
[Save][11]启动器
|
||||
|
||||
#### [Albert][38]
|
||||
|
||||
Albert 是一款快速、可扩展、可定制的生产力工具,受 Alfred(Mac 平台上一个非常好的生产力工具)启发并且仍处于开发阶段,它的目标是“使所有触手可及”。它能够与你的 Linux 发行版非常好的集成,帮助你提高生产力。
|
||||
|
||||
#### [Synapse][39]
|
||||
|
||||
Synapse 已经有些年头了,它是一个能够搜索和运行程序的简单启动器。它也同时能够加速一些工作流,譬如音乐控制、文件搜索、路径切换、书签、运行命令,等等。
|
||||
|
||||
正如 Abhishek 所考虑的,我们将根据读者的(也就是你的)反馈更新最佳 Linux 应用程序清单。那么,你最爱的 Linux 应用程序是什么呢?分享给我们或者为这个清单增加新的软件分类吧。
|
||||
|
||||
---
|
||||
|
||||
via: https://itsfoss.com/essential-linux-applications/
|
||||
|
||||
作者:[Munif Tanjim][a]
|
||||
译者:[cycoe](https://github.com/cycoe)
|
||||
校对:[校对者 ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux 中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/munif/
|
||||
[1]: http://pinterest.com/pin/create/bookmarklet/?media=https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Web-Browser-1024x512.jpg&url=https://itsfoss.com/essential-linux-applications/&is_video=false&description=Web%20Browsers
|
||||
[2]: http://pinterest.com/pin/create/bookmarklet/?media=https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Download-Manager-1024x512.jpg&url=https://itsfoss.com/essential-linux-applications/&is_video=false&description=Download%20Managers
|
||||
[3]: http://pinterest.com/pin/create/bookmarklet/?media=https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-BitTorrent-Client-1024x512.jpg&url=https://itsfoss.com/essential-linux-applications/&is_video=false&description=BitTorrent%20Clients
|
||||
[4]: http://pinterest.com/pin/create/bookmarklet/?media=https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Cloud-Storage-1024x512.jpg&url=https://itsfoss.com/essential-linux-applications/&is_video=false&description=Cloud%20Storages
|
||||
[5]: http://pinterest.com/pin/create/bookmarklet/?media=https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Communication-1024x512.jpg&url=https://itsfoss.com/essential-linux-applications/&is_video=false&description=Communication%20Apps
|
||||
[6]: http://pinterest.com/pin/create/bookmarklet/?media=https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Office-Suite-1024x512.jpg&url=https://itsfoss.com/essential-linux-applications/&is_video=false&description=Office%20Suites
|
||||
[7]: http://pinterest.com/pin/create/bookmarklet/?media=https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Music-Player-1024x512.jpg&url=https://itsfoss.com/essential-linux-applications/&is_video=false&description=Music%20Players
|
||||
[8]: http://pinterest.com/pin/create/bookmarklet/?media=https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Video-Player-1024x512.jpg&url=https://itsfoss.com/essential-linux-applications/&is_video=false&description=Video%20Player
|
||||
[9]: http://pinterest.com/pin/create/bookmarklet/?media=https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Photo-Editor-1024x512.jpg&url=https://itsfoss.com/essential-linux-applications/&is_video=false&description=Photo%20Editors
|
||||
[10]: http://pinterest.com/pin/create/bookmarklet/?media=https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Text-Editor-1024x512.jpg&url=https://itsfoss.com/essential-linux-applications/&is_video=false&description=Text%20Editors
|
||||
[11]: http://pinterest.com/pin/create/bookmarklet/?media=https://itsfoss.com/wp-content/uploads/2016/10/Essential-Linux-Apps-Launcher-1024x512.jpg&url=https://itsfoss.com/essential-linux-applications/&is_video=false&description=Launchers
|
||||
[12]: https://www.google.com/chrome/browser
|
||||
[13]: https://www.chromium.org/Home
|
||||
[14]: https://www.mozilla.org/en-US/firefox
|
||||
[15]: https://vivaldi.com
|
||||
[16]: http://ugetdm.com/
|
||||
[17]: http://xdman.sourceforge.net/
|
||||
[18]: http://deluge-torrent.org/
|
||||
[19]: https://transmissionbt.com/
|
||||
[20]: https://www.dropbox.com
|
||||
[21]: https://mega.nz/
|
||||
[22]: https://www.pidgin.im/
|
||||
[23]: https://itsfoss.com/franz-messaging-app/
|
||||
[24]: http://rambox.pro/
|
||||
[25]: https://www.skype.com
|
||||
[26]: https://itsfoss.com/skpe-alpha-linux/
|
||||
[27]: https://www.libreoffice.org
|
||||
[28]: https://www.wps.com
|
||||
[29]: http://gnumdk.github.io/lollypop-web/
|
||||
[30]: https://wiki.gnome.org/Apps/Rhythmbox
|
||||
[31]: https://cmus.github.io/
|
||||
[32]: http://www.videolan.org
|
||||
[33]: https://kodi.tv
|
||||
[34]: https://www.gimp.org/
|
||||
[35]: https://krita.org/en/
|
||||
[36]: https://atom.io/
|
||||
[37]: http://www.sublimetext.com/
|
||||
[38]: https://github.com/ManuelSchneid3r/albert
|
||||
[39]: https://launchpad.net/synapse-project
|
||||
[40]: https://itsfoss.com/otter-browser-review/
|
||||
[41]: https://itsfoss.com/4-best-download-managers-for-linux/
|
||||
[42]: https://itsfoss.com/best-torrent-ubuntu/
|
||||
[43]: https://itsfoss.com/cloud-services-linux/
|
||||
[44]: https://itsfoss.com/best-messaging-apps-linux/
|
||||
[45]: https://itsfoss.com/best-free-open-source-alternatives-microsoft-office/
|
||||
[46]: https://itsfoss.com/install-tomahawk-ubuntu-1404-linux-mint-17/
|
||||
[47]: https://itsfoss.com/format-factory-alternative-linux/
|
||||
[48]: https://itsfoss.com/image-applications-ubuntu-linux/
|
||||
[49]: https://itsfoss.com/best-modern-open-source-code-editors-for-linux/
|
@ -0,0 +1,236 @@
|
||||
如何在 Linux 中查看已挂载的文件系统类型
|
||||
======
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2018/07/filesystem-720x340.png)
|
||||
|
||||
如你所知,Linux 支持非常多的文件系统,例如 Ext4、ext3、ext2、sysfs、securityfs、FAT16、FAT32、NTFS 等等,当前被使用最多的文件系统是 Ext4。你曾经疑惑过你的 Linux 系统使用的是什么类型的文件系统吗?没有疑惑过?不用担心!我们将帮助你。本指南将解释如何在类 Unix 的操作系统中查看已挂载的文件系统类型。
|
||||
|
||||
### 在 Linux 中查看已挂载的文件系统类型
|
||||
|
||||
有很多种方法可以在 Linux 中查看已挂载的文件系统类型,下面我将给出 8 种不同的方法。那现在就让我们开始吧!
|
||||
|
||||
#### 方法 1 – 使用 `findmnt` 命令
|
||||
|
||||
这是查出文件系统类型最常使用的方法。**findmnt** 命令将列出所有已挂载的文件系统或者搜索出某个文件系统。`findmnt` 命令能够在 `/etc/fstab`、`/etc/mtab` 或 `/proc/self/mountinfo` 这几个文件中进行搜索。
|
||||
|
||||
`findmnt` 预装在大多数的 Linux 发行版中,因为它是 **util-linux** 包的一部分。为了防止 `findmnt` 命令不可用,你可以安装这个软件包。例如,你可以使用下面的命令在基于 Debian 的系统中安装 **util-linux** 包:
|
||||
```
|
||||
$ sudo apt install util-linux
|
||||
```
|
||||
|
||||
下面让我们继续看看如何使用 `findmnt` 来找出已挂载的文件系统。
|
||||
|
||||
假如你只敲 `findmnt` 命令而不带任何的参数或选项,它将像下面展示的那样以树状图形式列举出所有已挂载的文件系统。
|
||||
```
|
||||
$ findmnt
|
||||
```
|
||||
|
||||
**示例输出:**
|
||||
|
||||
![][2]
|
||||
|
||||
正如你看到的那样,`findmnt` 展示出了目标挂载点(TARGET)、源设备(SOURCE)、文件系统类型(FSTYPE)以及相关的挂载选项(OPTIONS),例如文件系统是否是可读可写或者只读的。以我的系统为例,我的根(`/`)文件系统的类型是 EXT4 。
|
||||
|
||||
假如你不想以树状图的形式来展示输出,可以使用 **-l** 选项来以简单平凡的形式来展示输出:
|
||||
```
|
||||
$ findmnt -l
|
||||
```
|
||||
|
||||
![][3]
|
||||
|
||||
你还可以使用 **-t** 选项来列举出特定类型的文件系统,例如下面展示的 **ext4** 文件系统类型:
|
||||
```
|
||||
$ findmnt -t ext4
|
||||
TARGET SOURCE FSTYPE OPTIONS
|
||||
/ /dev/sda2 ext4 rw,relatime,commit=360
|
||||
└─/boot /dev/sda1 ext4 rw,relatime,commit=360,data=ordered
|
||||
```
|
||||
|
||||
`findmnt` 还可以生成 `df` 类型的输出,使用命令
|
||||
```
|
||||
$ findmnt --df
|
||||
```
|
||||
或
|
||||
```
|
||||
$ findmnt -D
|
||||
```
|
||||
|
||||
**示例输出:**
|
||||
|
||||
```
|
||||
SOURCE FSTYPE SIZE USED AVAIL USE% TARGET
|
||||
dev devtmpfs 3.9G 0 3.9G 0% /dev
|
||||
run tmpfs 3.9G 1.1M 3.9G 0% /run
|
||||
/dev/sda2 ext4 456.3G 342.5G 90.6G 75% /
|
||||
tmpfs tmpfs 3.9G 32.2M 3.8G 1% /dev/shm
|
||||
tmpfs tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
|
||||
bpf bpf 0 0 0 - /sys/fs/bpf
|
||||
tmpfs tmpfs 3.9G 8.4M 3.9G 0% /tmp
|
||||
/dev/loop0 squashfs 82.1M 82.1M 0 100% /var/lib/snapd/snap/core/4327
|
||||
/dev/sda1 ext4 92.8M 55.7M 30.1M 60% /boot
|
||||
tmpfs tmpfs 788.8M 32K 788.8M 0% /run/user/1000
|
||||
gvfsd-fuse fuse.gvfsd-fuse 0 0 0 - /run/user/1000/gvfs
|
||||
```
|
||||
|
||||
你还可以展示某个特定设备或者挂载点的文件系统类型。
|
||||
|
||||
查看某个特定的设备:
|
||||
```
|
||||
$ findmnt /dev/sda1
|
||||
TARGET SOURCE FSTYPE OPTIONS
|
||||
/boot /dev/sda1 ext4 rw,relatime,commit=360,data=ordered
|
||||
```
|
||||
|
||||
查看某个特定的挂载点:
|
||||
```
|
||||
$ findmnt /
|
||||
TARGET SOURCE FSTYPE OPTIONS
|
||||
/ /dev/sda2 ext4 rw,relatime,commit=360
|
||||
```
|
||||
|
||||
你甚至还可以查看某个特定标签的文件系统的类型:
|
||||
```
|
||||
$ findmnt LABEL=Storage
|
||||
```
|
||||
|
||||
更多详情,请参考其 man 手册。
|
||||
```
|
||||
$ man findmnt
|
||||
```
|
||||
|
||||
`findmnt` 命令已足够完成在 Linux 中查看已挂载文件系统类型的任务,这个命令就是为了这个特定任务而生的。然而,还存在其他方法来查看文件系统的类型,假如你感兴趣的话,请接着让下看。
|
||||
|
||||
#### 方法 2 – 使用 `blkid` 命令
|
||||
|
||||
**blkid** 命令被用来查找和打印块设备的属性。它也是 **util-linux** 包的一部分,所以你不必再安装它。
|
||||
|
||||
为了使用 `blkid` 命令来查看某个文件系统的类型,可以运行:
|
||||
```
|
||||
$ blkid /dev/sda1
|
||||
```
|
||||
|
||||
#### 方法 3 – 使用 `df` 命令
|
||||
|
||||
在类 Unix 的操作系统中, **df** 命令被用来报告文件系统的磁盘空间使用情况。为了查看所有已挂载文件系统的类型,只需要运行:
|
||||
```
|
||||
$ df -T
|
||||
```
|
||||
|
||||
**示例输出:**
|
||||
|
||||
![][4]
|
||||
|
||||
关于 `df` 命令的更多细节,可以参考下面的指南。
|
||||
|
||||
- [针对新手的 df 命令教程](https://www.ostechnix.com/the-df-command-tutorial-with-examples-for-beginners/)
|
||||
|
||||
同样也可以参考其 man 手册:
|
||||
```
|
||||
$ man df
|
||||
```
|
||||
|
||||
#### 方法 4 – 使用 `file` 命令
|
||||
|
||||
**file** 命令可以判读出某个特定文件的类型,即便该文件没有文件后缀名也同样适用。
|
||||
|
||||
运行下面的命令来找出某个特定分区的文件系统类型:
|
||||
```
|
||||
$ sudo file -sL /dev/sda1
|
||||
[sudo] password for sk:
|
||||
/dev/sda1: Linux rev 1.0 ext4 filesystem data, UUID=83a1dbbf-1e15-4b45-94fe-134d3872af96 (needs journal recovery) (extents) (large files) (huge files)
|
||||
```
|
||||
|
||||
查看其 man 手册可以知晓更多细节:
|
||||
```
|
||||
$ man file
|
||||
```
|
||||
|
||||
#### 方法 5 – 使用 `fsck` 命令
|
||||
|
||||
**fsck** 命令被用来检查某个文件系统是否健全或者修复它。你可以像下面那样通过将分区名字作为 `fsck` 的参数来查看该分区的文件系统类型:
|
||||
|
||||
```
|
||||
$ fsck -N /dev/sda1
|
||||
fsck from util-linux 2.32
|
||||
[/usr/bin/fsck.ext4 (1) -- /boot] fsck.ext4 /dev/sda1
|
||||
```
|
||||
|
||||
如果想知道更多的内容,请查看其 man 手册:
|
||||
```
|
||||
$ man fsck
|
||||
```
|
||||
|
||||
#### 方法 6 – 使用 `fstab` 命令
|
||||
|
||||
**fstab** 是一个包含文件系统静态信息的文件。这个文件通常包含了挂载点、文件系统类型和挂载选项等信息。
|
||||
|
||||
要查看某个文件系统的类型,只需要运行:
|
||||
```
|
||||
$ cat /etc/fstab
|
||||
```
|
||||
|
||||
![][5]
|
||||
|
||||
更多详情,请查看其 man 手册:
|
||||
```
|
||||
$ man fstab
|
||||
```
|
||||
|
||||
#### 方法 7 – 使用 `lsblk` 命令
|
||||
|
||||
**lsblk** 命令可以展示设备的信息。
|
||||
|
||||
要展示已挂载文件系统的信息,只需运行:
|
||||
```
|
||||
$ lsblk -f
|
||||
NAME FSTYPE LABEL UUID MOUNTPOINT
|
||||
loop0 squashfs /var/lib/snapd/snap/core/4327
|
||||
sda
|
||||
├─sda1 ext4 83a1dbbf-1e15-4b45-94fe-134d3872af96 /boot
|
||||
├─sda2 ext4 4d25ddb0-5b20-40b4-ae35-ef96376d6594 /
|
||||
└─sda3 swap 1f8f5e2e-7c17-4f35-97e6-8bce7a4849cb [SWAP]
|
||||
sr0
|
||||
```
|
||||
|
||||
更多细节,可以参考它的 man 手册:
|
||||
```
|
||||
$ man lsblk
|
||||
```
|
||||
|
||||
#### 方法 8 – 使用 `mount` 命令
|
||||
|
||||
**mount** 被用来在类 Unix 系统中挂载本地或远程的文件系统。
|
||||
|
||||
要使用 `mount` 命令查看文件系统的类型,可以像下面这样做:
|
||||
```
|
||||
$ mount | grep "^/dev"
|
||||
/dev/sda2 on / type ext4 (rw,relatime,commit=360)
|
||||
/dev/sda1 on /boot type ext4 (rw,relatime,commit=360,data=ordered)
|
||||
```
|
||||
|
||||
更多详情,请参考其 man 手册的内容:
|
||||
```
|
||||
$ man mount
|
||||
```
|
||||
|
||||
好了,上面便是今天的全部内容了。现在你知道了 8 种不同的 Linux 命令来查看已挂载的 Linux 文件系统的类型。假如你知道其他的命令来完成同样的任务,请在下面的评论部分让我们知晓,我将确认并相应地升级本教程。
|
||||
|
||||
更过精彩内容即将呈现,请保持关注!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.ostechnix.com/how-to-find-the-mounted-filesystem-type-in-linux/
|
||||
|
||||
作者:[SK][a]
|
||||
选题:[lujun9972](https://github.com/lujun9972)
|
||||
译者:[FSSlc](https://github.com/FSSlc)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.ostechnix.com/author/sk/
|
||||
[1]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[2]:http://www.ostechnix.com/wp-content/uploads/2018/07/findmnt-1.png
|
||||
[3]:http://www.ostechnix.com/wp-content/uploads/2018/07/findmnt-2.png
|
||||
[4]:http://www.ostechnix.com/wp-content/uploads/2018/07/df.png
|
||||
[5]:http://www.ostechnix.com/wp-content/uploads/2018/07/fstab.png
|
@ -1,305 +1,245 @@
|
||||
|
||||
命令行:增强版
|
||||
======
|
||||
|
||||
我不确定有多少Web 开发者能完全逃避使用命令行。就我来说,我从1997年上大学就开始使用命令行了,那时的l33t-hacker 让我着迷,同时我也觉得它很难掌握。
|
||||
|
||||
过去这些年我的命令行本领在逐步加强,我经常会去搜寻在我工作中能使用的更好的命令行工具。下面就是我现在使用的用于增强原有命令行工具的列表。
|
||||
我不确定有多少 Web 开发者能完全避免使用命令行。就我来说,我从 1997 年上大学就开始使用命令行了,那时的 l33t-hacker 让我着迷,同时我也觉得它很难掌握。
|
||||
|
||||
过去这些年我的命令行本领在逐步加强,我经常会去搜寻工作中能用的更好的命令行工具。下面就是我现在使用的用于增强原有命令行工具的列表。
|
||||
|
||||
### 怎么忽略我所做的命令行增强
|
||||
|
||||
通常情况下我会用别名将新的或者增强的命令行工具链接到原来的命令行(如`cat`和`ping`)。
|
||||
|
||||
|
||||
如果我需要运行原来的命令的话(有时我确实需要这么做),我会像下面这样来运行未加修改的原来的命令行。(我用的是Mac,你的输出可能不一样)
|
||||
通常情况下我会用别名将新的增强的命令行工具链接到原来的命令(如 `cat` 和 `ping`)。
|
||||
|
||||
如果我需要运行原来的命令的话(有时我确实需要这么做),我会像下面这样来运行未加修改的原始命令。(我用的是 Mac,你的用法可能不一样)
|
||||
|
||||
```
|
||||
$ \cat # 忽略叫 "cat" 的别名 - 具体解释: https://stackoverflow.com/a/16506263/22617
|
||||
$ command cat # 忽略函数和别名
|
||||
|
||||
```
|
||||
|
||||
### bat > cat
|
||||
|
||||
`cat`用于打印文件的内容,如果你在命令行上要花很多时间的话,例如语法高亮之类的功能会非常有用。我首先发现了[ccat][3]这个有语法高亮功能的的工具,然后我发现了[bat][4],它的功能有语法高亮,分页,行号和git集成。
|
||||
|
||||
|
||||
`bat`命令也能让我在输出里(只要输出比屏幕的高度长)
|
||||
使用`/`关键字绑定来搜索(和用`less`搜索功能一样)。
|
||||
`cat` 用于打印文件的内容,如果你平时用命令行很多的话,例如语法高亮之类的功能会非常有用。我首先发现了 [ccat][3] 这个有语法高亮功能的工具,然后我发现了 [bat][4],它的功能有语法高亮,分页,行号和 git 集成。
|
||||
|
||||
`bat` 命令也能让我在输出里(多于一屏时)使用 `/` 搜索(和用 `less` 搜索功能一样)。
|
||||
|
||||
![Simple bat output][5]
|
||||
|
||||
我将别名`cat`链接到了`bat`命令:
|
||||
|
||||
|
||||
我将别名 `cat` 链接到了 `bat` 命令:
|
||||
|
||||
```
|
||||
alias cat='bat'
|
||||
|
||||
```
|
||||
|
||||
💾 [Installation directions][4]
|
||||
💾 [安装指引][4]
|
||||
|
||||
### prettyping > ping
|
||||
|
||||
`ping`非常有用,当我碰到“糟了,是不是什么服务挂了?/我的网不通了?”这种情况下我最先想到的工具就是它了。但是`prettyping`(“prettyping” 可不是指"pre typing")(译注:英文字面意思是'预打印')在`ping`上加上了友好的输出,这可让我感觉命令行友好了很多呢。
|
||||
|
||||
`ping` 非常有用,当我碰到“糟了,是不是 X 挂了?/我的网不通了?”这种情况下我最先想到的工具就是它了。但是 `prettyping`(“prettyping” 可不是指“pre typing”)在 `ping` 的基础上加了友好的输出,这可让我感觉命令行友好了很多呢。
|
||||
|
||||
![/images/cli-improved/ping.gif][6]
|
||||
|
||||
我也将`ping`用别名链接到了`prettyping`命令:
|
||||
|
||||
我也将 `ping` 用别名链接到了 `prettyping` 命令:
|
||||
|
||||
```
|
||||
alias ping='prettyping --nolegend'
|
||||
|
||||
```
|
||||
|
||||
💾 [Installation directions][7]
|
||||
💾 [安装指引][7]
|
||||
|
||||
### fzf > ctrl+r
|
||||
|
||||
在命令行上使用`ctrl+r`将允许你在命令历史里[反向搜索][8]使用过的命令,这是个挺好的小技巧,但是它需要你给出非常精确的输入才能正常运行。
|
||||
在命令行上使用 `ctrl+r` 将允许你在命令历史里[反向搜索][8]使用过的命令,这是个挺好的小技巧,但是它需要你给出非常精确的输入才能正常运行。
|
||||
|
||||
`fzf`这个工具相比于`ctrl+r`有了**巨大的**进步。它能针对命令行历史进行模糊查询,并且提供了对可能的合格结果进行全面交互式预览。
|
||||
`fzf` 这个工具相比于 `ctrl+r` 有了**巨大的**进步。它能针对命令行历史进行模糊查询,并且提供了对可能的合格结果进行全面交互式预览。
|
||||
|
||||
除了搜索命令历史,`fzf` 还能预览和打开文件,我在下面的视频里展示了这些功能。
|
||||
|
||||
除了搜索命令历史,`fzf`还能预览和打开文件,我在下面的视频里展示了这些功能。
|
||||
|
||||
|
||||
为了这个预览的效果,我创建了一个叫`preview`的别名,它将`fzf`和前文提到的`bat`组合起来完成预览功能,还给上面绑定了一个定制的热键Ctrl+o来打开 VS Code:
|
||||
|
||||
为了这个预览的效果,我创建了一个叫 `preview` 的别名,它将 `fzf` 和前文提到的 `bat` 组合起来完成预览功能,还给上面绑定了一个定制的热键 `ctrl+o` 来打开 VS Code:
|
||||
|
||||
```
|
||||
alias preview="fzf --preview 'bat --color \"always\" {}'"
|
||||
# 支持在 VS Code 里用ctrl+o 来打开选择的文件
|
||||
# 支持在 VS Code 里用 ctrl+o 来打开选择的文件
|
||||
export FZF_DEFAULT_OPTS="--bind='ctrl-o:execute(code {})+abort'"
|
||||
|
||||
```
|
||||
|
||||
💾 [Installation directions][9]
|
||||
💾 [安装指引][9]
|
||||
|
||||
### htop > top
|
||||
|
||||
`top`是当我想快速诊断为什么机器上的CPU跑的那么累或者风扇为什么突然呼呼大做的时候首先会想到的工具。我在产品环境也会使用这个工具。讨厌的是Mac上的`top`和 Linux 上的`top`有着极大的不同(恕我直言,应该是差的多)。
|
||||
`top` 是当我想快速诊断为什么机器上的 CPU 跑的那么累或者风扇为什么突然呼呼大做的时候首先会想到的工具。我在生产环境也会使用这个工具。讨厌的是 Mac 上的 `top` 和 Linux 上的 `top` 有着极大的不同(恕我直言,应该是差的多)。
|
||||
|
||||
不过,`htop` 是对 Linux 上的 `top` 和 Mac 上蹩脚的 `top` 的极大改进。它增加了包括颜色输出,键盘热键绑定以及不同的视图输出,这对理解进程之间的父子关系有极大帮助。
|
||||
|
||||
不过,`htop`是对 Linux 上的`top`和 Mac 上蹩脚的`top`的极大改进。它增加了包括颜色输出编码,键盘热键绑定以及不同的视图输出,这极大的帮助了我来理解进程之间的父子关系。
|
||||
|
||||
|
||||
方便的热键绑定包括:
|
||||
|
||||
* P - CPU使用率排序
|
||||
* M - 内存使用排序
|
||||
* F4 - 用字符串过滤进程(例如只看包括"node"的进程)
|
||||
* space - 锚定一个单独进程,这样我能观察它是否有尖峰状态
|
||||
一些很容易上手的热键:
|
||||
|
||||
* P - 按 CPU 使用率排序
|
||||
* M - 按内存使用排序
|
||||
* F4 - 用字符串过滤进程(例如只看包括 node 的进程)
|
||||
* space - 锚定一个单独进程,这样我能观察它是否有尖峰状态
|
||||
|
||||
![htop output][10]
|
||||
|
||||
在Mac Sieera 上htop 有个奇怪的bug,不过这个bug可以通过以root运行来绕过(我实在记不清这个bug 是什么,但是这个别名能搞定它,有点讨厌的是我得每次都输入root密码。):
|
||||
|
||||
在 Mac Sierra 上 htop 有个奇怪的 bug,不过这个 bug 可以通过以 root 运行来绕过(我实在记不清这个 bug 是什么,但是这个别名能搞定它,有点讨厌的是我得每次都输入 root 密码。):
|
||||
|
||||
```
|
||||
alias top="sudo htop" # 给top加上别名并且绕过 Sieera 上的bug
|
||||
alias top="sudo htop" # 给 top 加上别名并且绕过 Sierra 上的 bug
|
||||
```
|
||||
|
||||
💾 [Installation directions][11]
|
||||
💾 [安装指引][11]
|
||||
|
||||
### diff-so-fancy > diff
|
||||
|
||||
我非常确定我是一些年前从 Paul Irish 那儿学来的这个技巧,尽管我很少直接使用`diff`,但我的git命令行会一直使用`diff`。`diff-so-fancy`给了我代码语法颜色和更改字符高亮的功能。
|
||||
|
||||
我非常确定我是几年前从 Paul Irish 那儿学来的这个技巧,尽管我很少直接使用 `diff`,但我的 git 命令行会一直使用 `diff`。`diff-so-fancy` 给了我代码语法颜色和更改字符高亮的功能。
|
||||
|
||||
![diff so fancy][12]
|
||||
|
||||
在我的`~/.gitconfig`文件里我有下面的选项来打开`git diff`和`git show`的`diff-so-fancy`功能。
|
||||
|
||||
在我的 `~/.gitconfig` 文件里我用了下面的选项来打开 `git diff` 和 `git show` 的 `diff-so-fancy` 功能。
|
||||
|
||||
```
|
||||
[pager]
|
||||
diff = diff-so-fancy | less --tabs=1,5 -RFX
|
||||
show = diff-so-fancy | less --tabs=1,5 -RFX
|
||||
|
||||
diff = diff-so-fancy | less --tabs=1,5 -RFX
|
||||
show = diff-so-fancy | less --tabs=1,5 -RFX
|
||||
```
|
||||
|
||||
💾 [Installation directions][13]
|
||||
💾 [安装指引][13]
|
||||
|
||||
### fd > find
|
||||
|
||||
尽管我使用 Mac, 但我从来不是一个Spotlight的拥趸,我觉得它的性能很差,关键字也难记,加上更新它自己的数据库时会拖慢CPU,简直一无是处。我经常使用[Alfred][14],但是它的搜索功能也工作的不是很好。
|
||||
尽管我使用 Mac,但我绝不是 Spotlight 的粉丝,我觉得它的性能很差,关键字也难记,加上更新它自己的数据库时会拖慢 CPU,简直一无是处。我经常使用 [Alfred][14],但是它的搜索功能也不是很好。
|
||||
|
||||
我倾向于在命令行中搜索文件,但是 `find` 的难用在于很难去记住那些合适的表达式来描述我想要的文件。(而且 Mac 上的 `find` 命令和非 Mac 的 `find` 命令还有些许不同,这更加深了我的失望。)
|
||||
|
||||
我倾向于在命令行中搜索文件,但是`find`的难用在于很难去记住那些合适的表达式来描述我想要的文件。(而且 Mac 上的 find 命令和非Mac的find命令还有些许不同,这更加深了我的失望。)
|
||||
`fd` 是一个很好的替代品(它的作者和 `bat` 的作者是同一个人)。它非常快而且对于我经常要搜索的命令非常好记。
|
||||
|
||||
`fd`是一个很好的替代品(它的作者和`bat`的作者是同一个人)。它非常快而且对于我经常要搜索的命令非常好记。
|
||||
|
||||
|
||||
|
||||
几个使用方便的例子:
|
||||
几个上手的例子:
|
||||
|
||||
```
|
||||
$ fd cli # 所有包含"cli"的文件名
|
||||
$ fd -e md # 所有以.md作为扩展名的文件
|
||||
$ fd cli -x wc -w # 搜索"cli"并且在每个搜索结果上运行`wc -w`
|
||||
|
||||
|
||||
$ fd cli # 所有包含 "cli" 的文件名
|
||||
$ fd -e md # 所有以 .md 作为扩展名的文件
|
||||
$ fd cli -x wc -w # 搜索 "cli" 并且在每个搜索结果上运行 `wc -w`
|
||||
```
|
||||
|
||||
![fd output][15]
|
||||
|
||||
💾 [Installation directions][16]
|
||||
💾 [安装指引][16]
|
||||
|
||||
### ncdu > du
|
||||
|
||||
对我来说,知道当前的磁盘空间使用是非常重要的任务。我用过 Mac 上的[Dish Daisy][17],但是我觉得那个程序产生结果有点慢。
|
||||
对我来说,知道当前磁盘空间被什么占用了非常重要。我用过 Mac 上的 [DaisyDisk][17],但是我觉得那个程序产生结果有点慢。
|
||||
|
||||
`du -sh` 命令是我经常会跑的命令(`-sh` 是指结果以“汇总”和“人类可读”的方式显示),我经常会想要深入挖掘那些占用了大量磁盘空间的目录,看看到底是什么在占用空间。
|
||||
|
||||
`du -sh`命令是我经常会跑的命令(`-sh`是指结果以`总结`和`人类可读`的方式显示),我经常会想要深入挖掘那些占用了大量磁盘空间的目录,看看到底是什么在占用空间。
|
||||
|
||||
`ncdu`是一个非常棒的替代品。它提供了一个交互式的界面并且允许快速的扫描那些占用了大量磁盘空间的目录和文件,它又快又准。(尽管不管在哪个工具的情况下,扫描我的home目录都要很长时间,它有550G)
|
||||
|
||||
|
||||
一旦当我找到一个目录我想要“处理”一下(如删除,移动或压缩文件),我都会使用命令+点击屏幕[iTerm2][18]上部的目录名字来对那个目录执行搜索。
|
||||
`ncdu` 是一个非常棒的替代品。它提供了一个交互式的界面并且允许快速的扫描那些占用了大量磁盘空间的目录和文件,它又快又准。(尽管不管在哪个工具的情况下,扫描我的 home 目录都要很长时间,它有 550G)
|
||||
|
||||
一旦当我找到一个目录我想要“处理”一下(如删除,移动或压缩文件),我会使用 `commond+` 点击 [iTerm2][18] 上部的目录名字的方法在 Finder 中打开它。
|
||||
|
||||
![ncdu output][19]
|
||||
|
||||
还有另外一个选择[一个叫nnn的另外选择][20],它提供了一个更漂亮的界面,它也提供文件尺寸和使用情况,实际上它更像一个全功能的文件管理器。
|
||||
还有另外一个选择[一个叫 nnn 的另外选择][20],它提供了一个更漂亮的界面,它也提供文件尺寸和使用情况,实际上它更像一个全功能的文件管理器。
|
||||
|
||||
|
||||
我的`ncdu`使用下面的别名链接:
|
||||
我的 `ncdu` 使用下面的别名:
|
||||
|
||||
```
|
||||
alias du="ncdu --color dark -rr -x --exclude .git --exclude node_modules"
|
||||
|
||||
```
|
||||
|
||||
选项说明:
|
||||
|
||||
选项有:
|
||||
* `--color dark` 使用颜色方案
|
||||
* `-rr` 只读模式(防止误删和运行新的登陆程序)
|
||||
* `--exclude` 忽略不想操作的目录
|
||||
|
||||
* `--color dark` 使用颜色方案
|
||||
* `-rr` 只读模式(防止误删和运行新的登陆程序)
|
||||
* `--exclude` 忽略不想操作的目录
|
||||
|
||||
|
||||
|
||||
💾 [Installation directions][21]
|
||||
💾 [安装指引][21]
|
||||
|
||||
### tldr > man
|
||||
|
||||
几乎所有的单独命令行工具都有一个相伴的手册,其可以被`man <命令名>`来调出,但是在`man`的输出里找到东西可有点让人困惑,而且在一个包含了所有的技术细节的输出里找东西也挺可怕的。
|
||||
|
||||
|
||||
这就是TL;DR(译注:英文里`文档太长,没空去读`的缩写)项目创建的初衷。这是一个由社区驱动的文档系统,而且针对的是命令行。就我现在用下来,我还没碰到过一个命令它没有相应的文档,你[也可以做贡献][22]。
|
||||
几乎所有的命令行工具都有一个相伴的手册,它可以被 `man <命令名>` 来调出,但是在 `man` 的输出里找到东西可有点让人困惑,而且在一个包含了所有的技术细节的输出里找东西也挺可怕的。
|
||||
|
||||
这就是 TL;DR(译注:英文里“文档太长,没空去读”的缩写)项目创建的初衷。这是一个由社区驱动的文档系统,而且针对的是命令行。就我现在用下来,我还没碰到过一个命令没有它相应的文档,你[也可以做贡献][22]。
|
||||
|
||||
![TLDR output for 'fd'][23]
|
||||
|
||||
作为一个小技巧,我将`tldr`的别名链接到`help`(这样输入会快一点。。。)
|
||||
一个小技巧,我将 `tldr` 的别名链接到 `help`(这样输入会快一点……)
|
||||
|
||||
```
|
||||
alias help='tldr'
|
||||
|
||||
```
|
||||
|
||||
💾 [Installation directions][24]
|
||||
💾 [安装指引][24]
|
||||
|
||||
### ack || ag > grep
|
||||
|
||||
`grep`毫无疑问是一个命令行上的强力工具,但是这些年来它已经被一些工具超越了,其中两个叫`ack`和`ag`。
|
||||
`grep` 毫无疑问是一个强力的命令行工具,但是这些年来它已经被一些工具超越了,其中两个叫 `ack` 和 `ag`。
|
||||
|
||||
我个人对 `ack` 和 `ag` 都尝试过,而且没有非常明显的个人偏好,(那也就是说它们都很棒,并且很相似)。我倾向于默认只使用 `ack`,因为这三个字符就在指尖,很好打。并且 `ack` 有大量的 `ack --` 参数可以使用!(你一定会体会到这一点。)
|
||||
|
||||
我个人对`ack`和`ag`都尝试过,而且没有非常明显的个人偏好,(那也就是说他们都很棒,并且很相似)。我倾向于默认只使用`ack`,因为这三个字符就在指尖,很好打。并且,`ack`有大量的`ack --`参数可以使用,(你一定会体会到这一点。)
|
||||
|
||||
|
||||
`ack`和`ag`都将使用正则表达式来表达搜索,这非常契合我的工作,我能指定搜索的文件类型而不用使用类似于`--js`或`--html`的文件标识(尽管`ag`比`ack`在文件类型过滤器里包括了更多的文件类型。)
|
||||
|
||||
|
||||
两个工具都支持常见的`grep`选项,如`-B`和`-A`用于在搜索的上下文里指代`之前`和`之后`。
|
||||
`ack` 和 `ag` 都使用正则表达式来搜索,这非常契合我的工作,我能指定文件类型搜索,类似于 `--js` 或 `--html` 这种文件标识。(尽管 `ag` 比 `ack` 在文件类型过滤器里包括了更多的文件类型。)
|
||||
|
||||
两个工具都支持常见的 `grep` 选项,如 `-B` 和 `-A` 用于在搜索的上下文里指代“之前”和“之后”。
|
||||
|
||||
![ack in action][25]
|
||||
|
||||
因为`ack`不支持markdown(而我又恰好写了很多markdown), 我在我的`~/.ackrc`文件里放了如下的定制语句:
|
||||
|
||||
|
||||
因为 `ack` 不支持 markdown(而我又恰好写了很多 markdown),我在我的 `~/.ackrc` 文件里加了以下定制语句:
|
||||
|
||||
```
|
||||
--type-set=md=.md,.mkd,.markdown
|
||||
--pager=less -FRX
|
||||
|
||||
```
|
||||
|
||||
💾 Installation directions: [ack][26], [ag][27]
|
||||
💾 安装指引: [ack][26], [ag][27]
|
||||
|
||||
[Futher reading on ack & ag][28]
|
||||
[关于 ack & ag 的更多信息][28]
|
||||
|
||||
### jq > grep et al
|
||||
### jq > grep 及其它
|
||||
|
||||
我是[jq][29]的粉丝之一。当然一开始我也在它的语法里苦苦挣扎,好在我对查询语言还算有些使用心得,现在我对`jq`可以说是每天都要用。(不过从前我要么使用grep 或者使用一个叫[json][30]的工具,相比而言后者的功能就非常基础了。)
|
||||
我是 [jq][29] 的忠实粉丝之一。当然一开始我也在它的语法里苦苦挣扎,好在我对查询语言还算有些使用心得,现在我对 `jq` 可以说是每天都要用。(不过从前我要么使用 `grep` 或者使用一个叫 [json][30] 的工具,相比而言后者的功能就非常基础了。)
|
||||
|
||||
我甚至开始撰写一个 `jq` 的教程系列(有 2500 字并且还在增加),我还发布了一个[网页工具][31]和一个 Mac 上的应用(这个还没有发布。)
|
||||
|
||||
我甚至开始撰写一个`jq`的教程系列(有2500字并且还在增加),我还发布了一个[web tool][31]和一个Mac 上的应用(这个还没有发布。)
|
||||
|
||||
|
||||
`jq`允许我传入一个 JSON 并且能非常简单的将其转变为一个 使用JSON格式的结果,这正是我想要的。下面这个例子允许我用一个命令更新我的所有节点依赖(为了阅读方便,我将其分成为多行。)
|
||||
|
||||
`jq` 允许我传入一个 JSON 并且能非常简单的将其转变为一个使用 JSON 格式的结果,这正是我想要的。下面这个例子允许我用一个命令更新我的所有 node 依赖。(为了阅读方便,我将其分成为多行。)
|
||||
|
||||
```
|
||||
$ npm i $(echo $(\
|
||||
npm outdated --json | \
|
||||
jq -r 'to_entries | .[] | "\(.key)@\(.value.latest)"' \
|
||||
npm outdated --json | \
|
||||
jq -r 'to_entries | .[] | "\(.key)@\(.value.latest)"' \
|
||||
))
|
||||
|
||||
```
|
||||
上面的命令将使用npm 的 JSON 输出格式来列出所有的过期节点依赖,然后将下面的源JSON转换为:
|
||||
|
||||
上面的命令将使用 npm 的 JSON 输出格式来列出所有过期的 node 依赖,然后将下面的源 JSON 转换为:
|
||||
|
||||
```
|
||||
{
|
||||
"node-jq": {
|
||||
"current": "0.7.0",
|
||||
"wanted": "0.7.0",
|
||||
"latest": "1.2.0",
|
||||
"location": "node_modules/node-jq"
|
||||
},
|
||||
"uuid": {
|
||||
"current": "3.1.0",
|
||||
"wanted": "3.2.1",
|
||||
"latest": "3.2.1",
|
||||
"location": "node_modules/uuid"
|
||||
}
|
||||
"node-jq": {
|
||||
"current": "0.7.0",
|
||||
"wanted": "0.7.0",
|
||||
"latest": "1.2.0",
|
||||
"location": "node_modules/node-jq"
|
||||
},
|
||||
"uuid": {
|
||||
"current": "3.1.0",
|
||||
"wanted": "3.2.1",
|
||||
"latest": "3.2.1",
|
||||
"location": "node_modules/uuid"
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
转换结果为:(译注:原文此处并未给出结果)
|
||||
|
||||
上面的结果会被作为`npm install`的输入,你瞧,我的升级就这样全部搞定了。(当然,这里有点小题大做了。)
|
||||
上面的结果会被作为 `npm install` 的输入,你瞧,我的升级就这样全部搞定了。(当然,这里有点小题大做了。)
|
||||
|
||||
### 很荣幸提及一些其它的工具
|
||||
|
||||
### 很荣幸提及一些其他的工具
|
||||
|
||||
我也在开始尝试一些别的工具,但我还没有完全掌握他们。(除了`ponysay`,当我新启动一个命令行会话时,它就会出现。)
|
||||
|
||||
|
||||
* [ponysay][32] > cowsay
|
||||
* [csvkit][33] > awk et al
|
||||
* [noti][34] > `display notification`
|
||||
* [entr][35] > watch
|
||||
|
||||
我也在开始尝试一些别的工具,但我还没有完全掌握它们。(除了 `ponysay`,当我打开一个新的终端会话时,它就会出现。)
|
||||
|
||||
* [ponysay][32] > `cowsay`
|
||||
* [csvkit][33] > `awk 及其它`
|
||||
* [noti][34] > `display notification`
|
||||
* [entr][35] > `watch`
|
||||
|
||||
### 你有什么好点子吗?
|
||||
|
||||
|
||||
上面是我的命令行清单。能告诉我们你的吗?你有没有试着去增强一些你每天都会用到的命令呢?请告诉我,我非常乐意知道。
|
||||
|
||||
|
||||
上面是我的命令行清单。你的呢?你有没有试着去增强一些你每天都会用到的命令呢?请告诉我,我非常乐意知道。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -307,8 +247,8 @@ via: https://remysharp.com/2018/08/23/cli-improved
|
||||
|
||||
作者:[Remy Sharp][a]
|
||||
选题:[lujun9972](https://github.com/lujun9972)
|
||||
译者:DavidChenLiang(https://github.com/DavidChenLiang)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
译者:[DavidChenLiang](https://github.com/DavidChenLiang)
|
||||
校对:[pityonline](https://github.com/pityonline)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
@ -335,7 +275,7 @@ via: https://remysharp.com/2018/08/23/cli-improved
|
||||
[20]: https://github.com/jarun/nnn
|
||||
[21]: https://dev.yorhel.nl/ncdu
|
||||
[22]: https://github.com/tldr-pages/tldr#contributing
|
||||
[23]: https://remysharp.com/images/cli-improved/tldr.png (Sample tldr output for 'fd')
|
||||
[23]: https://remysharp.com/images/cli-improved/tldr.png (Sample tldr output for fd)
|
||||
[24]: http://tldr-pages.github.io/
|
||||
[25]: https://remysharp.com/images/cli-improved/ack.png (Sample ack output with grep args)
|
||||
[26]: https://beyondgrep.com
|
||||
|
@ -0,0 +1,94 @@
|
||||
# 10个最值得关注的树莓派博客
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/raspberry-pi-juggle.png?itok=oTgGGSRA)
|
||||
|
||||
网上有很多很棒的树莓派爱好者网站,教程,代码仓库,YouTube 频道和其他资源。以下是我最喜欢的十大树莓派博客,排名不分先后。
|
||||
|
||||
### 1. Raspberry Pi Spy
|
||||
|
||||
树莓派粉丝 Matt Hawkins 从很早开始就在他的网站 Raspberry Pi Spy 上撰写了大量全面且信息丰富的教程。我从这个网站上直接学到了很多东西,而且 Matt 似乎也总是第一个涵盖很多主题的人。在我学习使用树莓派的前三年里,多次在这个网站得到帮助。
|
||||
|
||||
让每个人感到幸运的是,这个不断采用新技术的网站仍然很强大。我希望看到它继续存在下去,让新社区成员在需要时得到帮助。
|
||||
|
||||
### 2. Adafruit
|
||||
|
||||
Adafruit 是硬件黑客中最知名的品牌之一。该公司制作和销售漂亮的硬件,并提供由员工、社区成员,甚至 Lady Ada 女士自己编写的优秀教程。
|
||||
|
||||
除了网上商店,Adafruit 还经营一个博客,这个博客充满了来自世界各地的精彩内容。在博客上可以查看树莓派的类别,特别是在工作日的最后一天,会在 Adafruit Towers 举办名为 [Friday is Pi Day][1] 的活动。
|
||||
|
||||
### 3. Recantha's Raspberry Pi Pod
|
||||
|
||||
Mike Horne(Recantha)是英国一位重要的树莓派社区成员,负责 [CamJam 和 Potton Pi&Pint][2](剑桥的两个树莓派社团)以及 [Pi Wars][3] (一年一度的树莓派机器人竞赛)。他为其他人建立树莓派社团提供建议,并且总是有时间帮助初学者。Horne和他的共同组织者 Tim Richardson 一起开发了 CamJam Edu Kit (一系列小巧且价格合理的套件,适合初学者使用 Python 学习物理计算)。
|
||||
|
||||
除此之外,他还运营着 Pi Pod,这是一个包含了世界各地树莓派相关内容的博客。它可能是这个列表中更新最频繁的树莓派博客,所以这是一个把握树莓派社区动向的极好方式。
|
||||
|
||||
### 4. Raspberry Pi blog
|
||||
|
||||
必须提一下树莓派的官方博客:[Raspberry Pi Foundation][4],这个博客涵盖了基金会的硬件,软件,教育,社区,慈善和青年编码俱乐部的一系列内容。博客上的大型主题是家庭数字化,教育授权,以及硬件版本和软件更新的官方新闻。
|
||||
|
||||
该博客自 [2011 年][5] 运行至今,并提供了自那时以来所有 1800 多个帖子的 [存档][6] 。你也可以在Twitter上关注[@raspberrypi_otd][7],这是我用 [Python][8] 创建的机器人(教程在这里:[Opensource.com][9])。Twitter 机器人推送来自博客存档的过去几年同一天的树莓派帖子。
|
||||
|
||||
### 5. RasPi.tv
|
||||
|
||||
另一位开创性的树莓派社区成员是 Alex Eames,通过他的博客和 YouTube 频道 RasPi.tv,他很早就加入了树莓派社区。他的网站为很多创客项目提供高质量、精心制作的视频教程和书面指南。
|
||||
|
||||
Alex 的网站 [RasP.iO][10] 制作了一系列树莓派附加板和配件,包括方便的 GPIO 端口引脚,电路板测量尺等等。他的博客也拓展到了 [Arduino][11],[WEMO][12] 以及其他小网站。
|
||||
|
||||
### 6. pyimagesearch
|
||||
|
||||
虽然不是严格的树莓派博客(名称中的“py”是“Python”,而不是“树莓派”),但该网站有着大量的 [树莓派种类][13]。 Adrian Rosebrock 获得了计算机视觉和机器学习领域的博士学位,他的博客旨在分享他在学习和制作自己的计算机视觉项目时所学到的机器学习技巧。
|
||||
|
||||
如果你想使用树莓派的相机模块学习面部或物体识别,来这个网站就对了。Adrian 在图像识别领域的深度学习和人工智能知识和实际应用是首屈一指的,而且他编写了自己的项目,这样任何人都可以进行尝试。
|
||||
|
||||
### 7. Raspberry Pi Roundup
|
||||
|
||||
这个博客由英国官方树莓派经销商之一 The Pi Hut 进行维护,会有每周的树莓派新闻。这是另一个很好的资源,可以紧跟树莓派社区的最新资讯,而且之前的文章也值得回顾。
|
||||
|
||||
### 8. Dave Akerman
|
||||
|
||||
Dave Akerman 是研究高空热气球的一流专家,他分享使用树莓派以最低的成本进行热气球发射方面的知识和经验。他会在一张由热气球拍摄的平流层照片下面对本次发射进行评论,也会对个人发射树莓派热气球给出自己的建议。
|
||||
|
||||
查看 Dave 的博客,了解精彩的临近空间摄影作品。
|
||||
|
||||
### 9. Pimoroni
|
||||
|
||||
Pimoroni 是一家世界知名的树莓派经销商,其总部位于英国谢菲尔德。这家经销商制作了著名的 [树莓派彩虹保护壳][14],并推出了许多极好的定制附加板和配件。
|
||||
|
||||
Pimoroni 的博客布局与其硬件设计和品牌推广一样精美,博文内容非常适合创客和业余爱好者在家进行创作,并且可以在有趣的 YouTube 频道 [Bilge Tank][15] 上找到。
|
||||
|
||||
### 10. Stuff About Code
|
||||
|
||||
Martin O'Hanlon 以树莓派社区成员的身份转为了基金会的员工,他起初出于乐趣在树莓派上开发我的世界作弊器,最近作为内容编辑加入了基金会。幸运的是,马丁的新工作并没有阻止他更新博客并与世界分享有益的趣闻。
|
||||
|
||||
除了我的世界的很多内容,你还可以在 Python 库,[Blue Dot][16] 和 [guizero][17] 上找到 Martin O'Hanlon 的贡献,以及一些总结性的树莓派技巧。
|
||||
|
||||
------
|
||||
|
||||
via: https://opensource.com/article/18/8/top-10-raspberry-pi-blogs-follow
|
||||
|
||||
作者:[Ben Nuttall][a]
|
||||
选题:[lujun9972](https://github.com/lujun9972)
|
||||
译者:[jlztan](https://github.com/jlztan)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/bennuttall
|
||||
[1]: https://blog.adafruit.com/category/raspberry-pi/
|
||||
[2]: https://camjam.me/?page_id=753
|
||||
[3]: https://piwars.org/
|
||||
[4]: https://www.raspberrypi-spy.co.uk/
|
||||
[5]: https://www.raspberrypi.org/blog/first-post/
|
||||
[6]: https://www.raspberrypi.org/blog/archive/
|
||||
[7]: https://twitter.com/raspberrypi_otd
|
||||
[8]: https://github.com/bennuttall/rpi-otd-bot/blob/master/src/bot.py
|
||||
[9]: https://opensource.com/article/17/8/raspberry-pi-twitter-bot
|
||||
[10]: https://rasp.io/
|
||||
[11]: https://www.arduino.cc/
|
||||
[12]: http://community.wemo.com/
|
||||
[13]: https://www.pyimagesearch.com/category/raspberry-pi/
|
||||
[14]: https://shop.pimoroni.com/products/pibow-for-raspberry-pi-3-b-plus
|
||||
[15]: https://www.youtube.com/channel/UCuiDNTaTdPTGZZzHm0iriGQ
|
||||
[16]: https://bluedot.readthedocs.io/en/latest/#
|
||||
[17]: https://lawsie.github.io/guizero/
|
||||
|
@ -0,0 +1,538 @@
|
||||
将 Grails 与 jQuery 和 DataTables 一起使用
|
||||
======
|
||||
|
||||
本文介绍如何构建一个基于 Grails 的数据浏览器来可视化复杂的表格数据。
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/data_container_block.png?itok=S8MbXEYw)
|
||||
|
||||
我是 [Grails][1] 的忠实粉丝。当然,我主要是热衷于利用命令行工具来探索和分析数据的数据人。数据人经常需要_查看_数据,这也意味着他们通常拥有优秀的数据浏览器。利用 Grails,[jQuery][2],以及 [DataTables jQuery 插件][3],我们可以制作出非常友好的表格数据浏览器。
|
||||
|
||||
[DataTables 网站][3]提供了许多“食谱风格”的教程文档,展示了如何组合一些优秀的示例应用程序,这些程序包含了完成一些非常漂亮的东西所必要的 JavaScript,HTML,以及偶尔出现的 [PHP][4]。但对于那些宁愿使用 Grails 作为后端的人来说,有必要进行一些说明示教。此外,样本程序中使用的数据是虚构公司的员工的单个平面表数据,因此处理这些复杂的表关系可以作为读者的一个练习项目。
|
||||
|
||||
本文中,我们将创建具有略微复杂的数据结构和 DataTables 浏览器的 Grails 应用程序。我们将介绍 Grails 标准 [Groovy][5]-fied Java Hibernate 标准。我已将代码托管在 [GitHub][6] 上方便大家访问,因此本文主要是对代码细节的解读。
|
||||
|
||||
首先,你需要配置 Java,Groovy,Grails 的使用环境。对于 Grails,我倾向于使用终端窗口和 [Vim][7],本文也使用它们。为获得现代 Java,建议下载并安装 Linux 发行版提供的 [Open Java Development Kit][8] (OpenJDK)(应该是 Java 8,9,10或11,撰写本文时,我正在使用 Java 8)。从我的角度来看,获取最新的 Groovy 和 Grails 的最佳方法是使用 [SKDMAN!][9]。
|
||||
|
||||
从未尝试过 Grails 的读者可能需要做一些背景资料阅读。作为初学者,推荐文章 [创建你的第一个 Grails 应用程序][10]。
|
||||
|
||||
### 获取员工信息浏览器应用程序
|
||||
|
||||
正如上文所提,我将本文中员工信息浏览器的源代码托管在 [GitHub][6]上。进一步讲,应用程序 **embrow** 是在 Linux 终端中用如下命令构建的:
|
||||
|
||||
```
|
||||
cd Projects
|
||||
grails create-app com.nuevaconsulting.embrow
|
||||
```
|
||||
|
||||
域类和单元测试创建如下:
|
||||
|
||||
```
|
||||
grails create-domain-class com.nuevaconsulting.embrow.Position
|
||||
grails create-domain-class com.nuevaconsulting.embrow.Office
|
||||
grails create-domain-class com.nuevaconsulting.embrow.Employeecd embrowgrails createdomaincom.grails createdomaincom.grails createdomaincom.
|
||||
```
|
||||
|
||||
这种方式构建的域类没有属性,因此必须按如下方式编辑它们:
|
||||
|
||||
Position 域类:
|
||||
|
||||
```
|
||||
package com.nuevaconsulting.embrow
|
||||
|
||||
class Position {
|
||||
|
||||
String name
|
||||
int starting
|
||||
|
||||
static constraints = {
|
||||
name nullable: false, blank: false
|
||||
starting nullable: false
|
||||
}
|
||||
}com.Stringint startingstatic constraintsnullableblankstarting nullable
|
||||
```
|
||||
|
||||
Office 域类:
|
||||
|
||||
```
|
||||
package com.nuevaconsulting.embrow
|
||||
|
||||
class Office {
|
||||
|
||||
String name
|
||||
String address
|
||||
String city
|
||||
String country
|
||||
|
||||
static constraints = {
|
||||
name nullable: false, blank: false
|
||||
address nullable: false, blank: false
|
||||
city nullable: false, blank: false
|
||||
country nullable: false, blank: false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Enployee 域类:
|
||||
|
||||
```
|
||||
package com.nuevaconsulting.embrow
|
||||
|
||||
class Employee {
|
||||
|
||||
String surname
|
||||
String givenNames
|
||||
Position position
|
||||
Office office
|
||||
int extension
|
||||
Date hired
|
||||
int salary
|
||||
static constraints = {
|
||||
surname nullable: false, blank: false
|
||||
givenNames nullable: false, blank: false
|
||||
: false
|
||||
office nullable: false
|
||||
extension nullable: false
|
||||
hired nullable: false
|
||||
salary nullable: false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
请注意,虽然 Position 和 Office 域类使用了预定义的 Groovy 类型 String 以及 int,但 Employee 域类定义了 Position 和 Office 字段(以及预定义的 Date)。这会导致创建数据库表,其中存储的 Employee 实例中包含了指向存储 Position 和 Office 实例表的引用或者外键。
|
||||
|
||||
现在你可以生成控制器,视图,以及其他各种测试组件:
|
||||
|
||||
```
|
||||
-all com.nuevaconsulting.embrow.Position
|
||||
grails generate-all com.nuevaconsulting.embrow.Office
|
||||
grails generate-all com.nuevaconsulting.embrow.Employeegrails generateall com.grails generateall com.grails generateall com.
|
||||
```
|
||||
|
||||
此时,你已经准备好基本的 create-read-update-delete(CRUD)应用程序。我在**grails-app/init/com/nuevaconsulting/BootStrap.groovy**中包含了一些基础数据来填充表格。
|
||||
|
||||
如果你用如下命令来启动应用程序:
|
||||
|
||||
```
|
||||
grails run-app
|
||||
```
|
||||
|
||||
在浏览器输入**<http://localhost:8080/:>**,你将会看到如下界面:
|
||||
|
||||
![Embrow home screen][12]
|
||||
|
||||
Embrow 应用程序主界面。
|
||||
|
||||
单击 OfficeController,会跳转到如下界面:
|
||||
|
||||
![Office list][14]
|
||||
|
||||
Office 列表
|
||||
|
||||
注意,此表由 **OfficeController index** 生成,并由视图 `office/index.gsp` 显示。
|
||||
|
||||
同样,单击 **EmployeeController** 跳转到如下界面:
|
||||
|
||||
![Employee controller][16]
|
||||
|
||||
employee controller
|
||||
|
||||
好吧,这很丑陋: Position 和 Office 链接是什么?
|
||||
|
||||
上面的命令 `generate-all` 生成的视图创建了一个叫 **index.gsp** 的文件,它使用 Grails <f:table/> 标签,该标签默认会显示类名(**com.nuevaconsulting.embrow.Position**)和持久化示例标识符(**30**)。这个操作可以自定义用来产生更好看的东西,并且自动生成链接,自动生成分页以及自动生成可拍序列的一些非常简洁直观的东西。
|
||||
|
||||
但该员工信息浏览器功能也是有限的。例如,如果想查找 position 信息中包含 “dev” 的员工该怎么办?如果要组合排序,以姓氏为主排序关键字,office 为辅助排序关键字,该怎么办?或者,你需要将已排序的数据导出到电子表格或 PDF 文档以便通过电子邮件发送给无法访问浏览器的人,该怎么办?
|
||||
|
||||
jQuery DataTables 插件提供了这些所需的功能。允许你创建一个完成的表格数据浏览器。
|
||||
|
||||
### 创建员工信息浏览器视图和控制器的方法
|
||||
|
||||
要基于 jQuery DataTables 创建员工信息浏览器,你必须先完成以下两个任务:
|
||||
1. 创建 Grails 视图,其中包含启用 DataTable 所需的 HTML 和 JavaScript
|
||||
|
||||
|
||||
#### 员工信息浏览器视图
|
||||
|
||||
在目录 **embrow/grails-app/views/employee** 中,首先复制 **index.gsp** 文件,重命名为 **browser.gsp**:
|
||||
|
||||
```
|
||||
cd Projects
|
||||
cd embrow/grails-app/views/employee
|
||||
cp gsp browser.gsp
|
||||
```
|
||||
|
||||
此刻,你自定义新的 **browser.gsp** 文件来添加相关的 jQuery DataTables 代码。
|
||||
|
||||
通常,在可能的时候,我喜欢从内容提供商处获得 JavaScript 和 CSS;在下面这行后面:
|
||||
|
||||
```
|
||||
<title><g:message code="default.list.label" args="[entityName]" /></title>
|
||||
```
|
||||
|
||||
插入如下代码:
|
||||
|
||||
```
|
||||
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.css">
|
||||
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/scroller/1.4.4/css/scroller.dataTables.min.css">
|
||||
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/scroller/1.4.4/js/dataTables.scroller.min.js"></script>
|
||||
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/buttons/1.5.1/js/dataTables.buttons.min.js"></script>
|
||||
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/buttons/1.5.1/js/buttons.flash.min.js"></script>
|
||||
<script type="text/javascript" charset="utf8" src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
|
||||
<script type="text/javascript" charset="utf8" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.32/pdfmake.min.js"></script>
|
||||
<script type="text/javascript" charset="utf8" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.32/vfs_fonts.js"></script>
|
||||
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/buttons/1.5.1/js/buttons.html5.min.js"></script>
|
||||
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/buttons/1.5.1/js/buttons.print.min.js "></script>
|
||||
```
|
||||
|
||||
然后删除 **index.gsp** 中提供数据分页的代码:
|
||||
|
||||
```
|
||||
<div id="list-employee" class="content scaffold-list" role="main">
|
||||
<h1><g:message code="default.list.label" args="[entityName]" /></h1>
|
||||
<g:if test="${flash.message}">
|
||||
<div class="message" role="status">${flash.message}</div>
|
||||
</g:if>
|
||||
<f:table collection="${employeeList}" />
|
||||
|
||||
<div class="pagination">
|
||||
<g:paginate total="${employeeCount ?: 0}" />
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
并插入实现 jQuery DataTables 的代码。
|
||||
|
||||
要插入的第一部分是 HTML,它将创建浏览器的基本表格结构。DataTables 与后端通信的应用程序来说,它们只提供表格页眉和页脚;DataTables JavaScript 则负责表中内容。
|
||||
|
||||
```
|
||||
<div id="employee-browser" class="content" role="main">
|
||||
<h1>Employee Browser</h1>
|
||||
<table id="employee_dt" class="display compact" style="width:99%;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Surname</th>
|
||||
<th>Given name(s)</th>
|
||||
<th>Position</th>
|
||||
<th>Office</th>
|
||||
<th>Extension</th>
|
||||
<th>Hired</th>
|
||||
<th>Salary</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th>Surname</th>
|
||||
<th>Given name(s)</th>
|
||||
<th>Position</th>
|
||||
<th>Office</th>
|
||||
<th>Extension</th>
|
||||
<th>Hired</th>
|
||||
<th>Salary</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
```
|
||||
|
||||
接下来,插入一个 JavaScript 块,它主要提供三个功能:它设置页脚中显示的文本框的大小,以进行列过滤,建立 DataTables 表模型,并创建一个处理程序来进行列过滤。
|
||||
|
||||
```
|
||||
<g:javascript>
|
||||
$('#employee_dt tfoot th').each( function() {javascript
|
||||
```
|
||||
|
||||
下面的代码处理表格列底部的过滤器框的大小:
|
||||
|
||||
```
|
||||
var title = $(this).text();
|
||||
if (title == 'Extension' || title == 'Hired')
|
||||
$(this).html('<input type="text" size="5" placeholder="' + title + '?" />');
|
||||
else
|
||||
$(this).html('<input type="text" size="15" placeholder="' + title + '?" />');
|
||||
});titletitletitletitletitle
|
||||
```
|
||||
|
||||
接下来,定义表模型。 这是提供所有表选项的地方,包括界面的滚动,而不是分页,根据 dom 字符串提供的装饰,将数据导出为 CSV 和其他格式的能力,以及建立与服务器的 Ajax 连接。 请注意,使用 Groovy GString 调用 Grails **createLink()** 的方法创建 URL,在 **EmployeeController** 中指向 **browserLister** 操作。同样有趣的是表格列的定义。此信息将发送到后端,后端查询数据库并返回相应的记录。
|
||||
|
||||
```
|
||||
var table = $('#employee_dt').DataTable( {
|
||||
"scrollY": 500,
|
||||
"deferRender": true,
|
||||
"scroller": true,
|
||||
"dom": "Brtip",
|
||||
"buttons": [ 'copy', 'csv', 'excel', 'pdf', 'print' ],
|
||||
"processing": true,
|
||||
"serverSide": true,
|
||||
"ajax": {
|
||||
"url": "${createLink(controller: 'employee', action: 'browserLister')}",
|
||||
"type": "POST",
|
||||
},
|
||||
"columns": [
|
||||
{ "data": "surname" },
|
||||
{ "data": "givenNames" },
|
||||
{ "data": "position" },
|
||||
{ "data": "office" },
|
||||
{ "data": "extension" },
|
||||
{ "data": "hired" },
|
||||
{ "data": "salary" }
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
最后,监视过滤器列以进行更改,并使用它们来应用过滤器。
|
||||
|
||||
```
|
||||
table.columns().every(function() {
|
||||
var that = this;
|
||||
$('input', this.footer()).on('keyup change', function(e) {
|
||||
if (that.search() != this.value && 8 < e.keyCode && e.keyCode < 32)
|
||||
that.search(this.value).draw();
|
||||
});
|
||||
```
|
||||
|
||||
这就是 JavaScript,这样就完成了对视图代码的更改。
|
||||
|
||||
```
|
||||
});
|
||||
</g:javascript>
|
||||
```
|
||||
|
||||
以下是此视图创建的UI的屏幕截图:
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/screen_4.png)
|
||||
|
||||
这是另一个屏幕截图,显示了过滤和多列排序(寻找 position 包括字符 “dev” 的员工,先按 office 排序,然后按姓氏排序):
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/screen_5.png)
|
||||
|
||||
这是另一个屏幕截图,显示单击 CSV 按钮时会发生什么:
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/screen6.png)
|
||||
|
||||
最后,这是一个截图,显示在 LibreOffice 中打开的 CSV 数据:
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/screen7.png)
|
||||
|
||||
好的,视图部分看起来非常简单; 因此,控制器必须做所有繁重的工作,对吧? 让我们来看看…
|
||||
|
||||
#### 控制器 browserLister 操作
|
||||
|
||||
回想一下,我们看到过这个字符串
|
||||
|
||||
```
|
||||
"${createLink(controller: 'employee', action: 'browserLister')}"
|
||||
```
|
||||
|
||||
对于从 DataTables 模型中调用 Ajax 的 URL,是在 Grails 服务器上动态创建 HTML 链接,其 Grails 标记背后通过调用 [createLink()][17] 的方法实现的。这会最终产生一个指向 **EmployeeController** 的链接,位于:
|
||||
|
||||
```
|
||||
embrow/grails-app/controllers/com/nuevaconsulting/embrow/EmployeeController.groovy
|
||||
```
|
||||
|
||||
特别是控制器方法 **browserLister()**。我在代码中留了一些 print 语句,以便在运行时能够在终端看到中间结果。
|
||||
|
||||
```
|
||||
def browserLister() {
|
||||
// Applies filters and sorting to return a list of desired employees
|
||||
```
|
||||
|
||||
首先,打印出传递给 **browserLister()** 的参数。我通常使用此代码开始构建控制器方法,以便我完全清楚我的控制器正在接收什么。
|
||||
|
||||
```
|
||||
println "employee browserLister params $params"
|
||||
println()
|
||||
```
|
||||
|
||||
接下来,处理这些参数以使它们更加有用。首先,jQuery DataTables 参数,一个名为 **jqdtParams**的 Groovy 映射:
|
||||
|
||||
```
|
||||
def jqdtParams = [:]
|
||||
params.each { key, value ->
|
||||
def keyFields = key.replace(']','').split(/\[/)
|
||||
def table = jqdtParams
|
||||
for (int f = 0; f < keyFields.size() - 1; f++) {
|
||||
def keyField = keyFields[f]
|
||||
if (!table.containsKey(keyField))
|
||||
table[keyField] = [:]
|
||||
table = table[keyField]
|
||||
}
|
||||
table[keyFields[-1]] = value
|
||||
}
|
||||
println "employee dataTableParams $jqdtParams"
|
||||
println()
|
||||
```
|
||||
|
||||
接下来,列数据,一个名为 **columnMap**的 Groovy 映射:
|
||||
|
||||
```
|
||||
def columnMap = jqdtParams.columns.collectEntries { k, v ->
|
||||
def whereTerm = null
|
||||
switch (v.data) {
|
||||
case 'extension':
|
||||
case 'hired':
|
||||
case 'salary':
|
||||
if (v.search.value ==~ /\d+(,\d+)*/)
|
||||
whereTerm = v.search.value.split(',').collect { it as Integer }
|
||||
break
|
||||
default:
|
||||
if (v.search.value ==~ /[A-Za-z0-9 ]+/)
|
||||
whereTerm = "%${v.search.value}%" as String
|
||||
break
|
||||
}
|
||||
[(v.data): [where: whereTerm]]
|
||||
}
|
||||
println "employee columnMap $columnMap"
|
||||
println()
|
||||
```
|
||||
|
||||
接下来,从 **columnMap** 中检索的所有列表,以及在视图中应如何排序这些列表,Groovy 列表分别称为 **allColumnList**和 **orderList**:
|
||||
|
||||
```
|
||||
def allColumnList = columnMap.keySet() as List
|
||||
println "employee allColumnList $allColumnList"
|
||||
def orderList = jqdtParams.order.collect { k, v -> [allColumnList[v.column as Integer], v.dir] }
|
||||
println "employee orderList $orderList"
|
||||
```
|
||||
|
||||
我们将使用 Grails 的 Hibernate 标准实现来实际选择要显示的元素以及它们的排序和分页。标准要求过滤器关闭; 在大多数示例中,这是作为标准实例本身的创建的一部分给出的,但是在这里我们预先定义过滤器闭包。请注意,在这种情况下,“date hired” 过滤器的相对复杂的解释被视为一年并应用于建立日期范围,并使用 **createAlias** 以允许我们进入相关类别 Position 和 Office:
|
||||
|
||||
```
|
||||
def filterer = {
|
||||
createAlias 'position', 'p'
|
||||
createAlias 'office', 'o'
|
||||
|
||||
if (columnMap.surname.where) ilike 'surname', columnMap.surname.where
|
||||
if (columnMap.givenNames.where) ilike 'givenNames', columnMap.givenNames.where
|
||||
if (columnMap.position.where) ilike 'p.name', columnMap.position.where
|
||||
if (columnMap.office.where) ilike 'o.name', columnMap.office.where
|
||||
if (columnMap.extension.where) inList 'extension', columnMap.extension.where
|
||||
if (columnMap.salary.where) inList 'salary', columnMap.salary.where
|
||||
if (columnMap.hired.where) {
|
||||
if (columnMap.hired.where.size() > 1) {
|
||||
or {
|
||||
columnMap.hired.where.each {
|
||||
between 'hired', Date.parse('yyyy/MM/dd',"${it}/01/01" as String),
|
||||
Date.parse('yyyy/MM/dd',"${it}/12/31" as String)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
between 'hired', Date.parse('yyyy/MM/dd',"${columnMap.hired.where[0]}/01/01" as String),
|
||||
Date.parse('yyyy/MM/dd',"${columnMap.hired.where[0]}/12/31" as String)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
是时候应用上述内容了。第一步是获取分页代码所需的所有 Employee 实例的总数:
|
||||
|
||||
```
|
||||
def recordsTotal = Employee.count()
|
||||
println "employee recordsTotal $recordsTotal"
|
||||
```
|
||||
|
||||
接下来,将过滤器应用于 Employee 实例以获取过滤结果的计数,该结果将始终小于或等于总数(同样,这是针对分页代码):
|
||||
|
||||
```
|
||||
def c = Employee.createCriteria()
|
||||
def recordsFiltered = c.count {
|
||||
filterer.delegate = delegate
|
||||
filterer()
|
||||
}
|
||||
println "employee recordsFiltered $recordsFiltered"
|
||||
|
||||
```
|
||||
|
||||
获得这两个计数后,你还可以使用分页和排序信息获取实际过滤的实例。
|
||||
|
||||
```
|
||||
def orderer = Employee.withCriteria {
|
||||
filterer.delegate = delegate
|
||||
filterer()
|
||||
orderList.each { oi ->
|
||||
switch (oi[0]) {
|
||||
case 'surname': order 'surname', oi[1]; break
|
||||
case 'givenNames': order 'givenNames', oi[1]; break
|
||||
case 'position': order 'p.name', oi[1]; break
|
||||
case 'office': order 'o.name', oi[1]; break
|
||||
case 'extension': order 'extension', oi[1]; break
|
||||
case 'hired': order 'hired', oi[1]; break
|
||||
case 'salary': order 'salary', oi[1]; break
|
||||
}
|
||||
}
|
||||
maxResults (jqdtParams.length as Integer)
|
||||
firstResult (jqdtParams.start as Integer)
|
||||
}
|
||||
```
|
||||
|
||||
要完全清楚,JTable 中的分页代码管理三个计数:数据集中的记录总数,应用过滤器后得到的数字,以及要在页面上显示的数字(显示是滚动还是分页)。 排序应用于所有过滤的记录,并且分页应用于那些过滤的记录的块以用于显示目的。
|
||||
|
||||
接下来,处理命令返回的结果,在每行中创建指向 Employee,Position 和 Office 实例的链接,以便用户可以单击这些链接以获取相关实例的所有详细信息:
|
||||
|
||||
```
|
||||
def dollarFormatter = new DecimalFormat('$##,###.##')
|
||||
def employees = orderer.collect { employee ->
|
||||
['surname': "<a href='${createLink(controller: 'employee', action: 'show', id: employee.id)}'>${employee.surname}</a>",
|
||||
'givenNames': employee.givenNames,
|
||||
'position': "<a href='${createLink(controller: 'position', action: 'show', id: employee.position?.id)}'>${employee.position?.name}</a>",
|
||||
'office': "<a href='${createLink(controller: 'office', action: 'show', id: employee.office?.id)}'>${employee.office?.name}</a>",
|
||||
'extension': employee.extension,
|
||||
'hired': employee.hired.format('yyyy/MM/dd'),
|
||||
'salary': dollarFormatter.format(employee.salary)]
|
||||
}
|
||||
```
|
||||
|
||||
最后,创建要返回的结果并将其作为 JSON 返回,这是 jQuery DataTables 所需要的。
|
||||
|
||||
```
|
||||
def result = [draw: jqdtParams.draw, recordsTotal: recordsTotal, recordsFiltered: recordsFiltered, data: employees]
|
||||
render(result as JSON)
|
||||
}
|
||||
```
|
||||
|
||||
大功告成
|
||||
如果你熟悉 Grails,这可能看起来比你原先想象的要多,但这里没有火箭式的一步到位方法,只是很多分散的操作步骤。但是,如果你没有太多接触 Grails(或 Groovy),那么需要了解很多新东西 - 闭包,代理和构建器等等。
|
||||
|
||||
在那种情况下,从哪里开始? 最好的地方是了解 Groovy 本身,尤其是 [Groovy closures][18] 和 [Groovy delegates and builders][19]。然后再去阅读上面关于 Grails 和 Hibernate 条件查询的建议阅读文章。
|
||||
|
||||
### 结语
|
||||
|
||||
jQuery DataTables 为 Grails 制作了很棒的表格数据浏览器。对视图进行编码并不是太棘手,但DataTables 文档中提供的 PHP 示例提供的功能仅到此位置。特别是,它们不是用 Grails 程序员编写的,也不包含探索使用引用其他类(实质上是查找表)的元素的更精细的细节。
|
||||
|
||||
我使用这种方法制作了几个数据浏览器,允许用户选择要查看和累积记录计数的列,或者只是浏览数据。即使在相对适度的 VPS 上的百万行表中,性能也很好。
|
||||
|
||||
一个警告:我偶然发现了 Grails 中暴露的各种 Hibernate 标准机制的一些问题(请参阅我的其他 GitHub 代码库),因此需要谨慎和实验。如果所有其他方法都失败了,另一种方法是动态构建 SQL 字符串并执行它们。在撰写本文时,我更喜欢使用 Grails 标准,除非我遇到杂乱的子查询,但这可能只反映了我在 Hibernate 中对子查询的相对缺乏经验。
|
||||
|
||||
我希望 Grails 程序员发现本文的有趣性。请随时在下面留下评论或建议。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/18/9/using-grails-jquery-and-datatables
|
||||
|
||||
作者:[Chris Hermansen][a]
|
||||
选题:[lujun9972](https://github.com/lujun9972)
|
||||
译者:[jrg](https://github.com/jrglinux)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/clhermansen
|
||||
[1]: https://grails.org/
|
||||
[2]: https://jquery.com/
|
||||
[3]: https://datatables.net/
|
||||
[4]: http://php.net/
|
||||
[5]: http://groovy-lang.org/
|
||||
[6]: https://github.com/monetschemist/grails-datatables
|
||||
[7]: https://www.vim.org/
|
||||
[8]: http://openjdk.java.net/
|
||||
[9]: http://sdkman.io/
|
||||
[10]: http://guides.grails.org/creating-your-first-grails-app/guide/index.html
|
||||
[11]: https://opensource.com/file/410061
|
||||
[12]: https://opensource.com/sites/default/files/uploads/screen_1.png "Embrow home screen"
|
||||
[13]: https://opensource.com/file/410066
|
||||
[14]: https://opensource.com/sites/default/files/uploads/screen_2.png "Office list screenshot"
|
||||
[15]: https://opensource.com/file/410071
|
||||
[16]: https://opensource.com/sites/default/files/uploads/screen3.png "Employee controller screenshot"
|
||||
[17]: https://gsp.grails.org/latest/ref/Tags/createLink.html
|
||||
[18]: http://groovy-lang.org/closures.html
|
||||
[19]: http://groovy-lang.org/dsls.html
|
@ -0,0 +1,76 @@
|
||||
适用于小型企业的 4 个开源发票工具
|
||||
======
|
||||
用基于 web 的发票软件管理你的账单,完成收款,十分简单。
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BUS_lovemoneyglory2.png?itok=AvneLxFp)
|
||||
|
||||
无论您开办小型企业的原因是什么,保持业务发展的关键是可以盈利。收款也就意味着向客户提供发票。
|
||||
|
||||
使用 LibreOffice Writer 或 LibreOffice Calc 提供发票很容易,但有时候你需要的不止这些。从更专业的角度看。一种跟进发票的方法。提醒你何时跟进你发出的发票。
|
||||
|
||||
在这里有各种各样的商业闭源发票管理工具。但是开源界的产品和相对应的闭源商业工具比起来,并不差,没准还更灵活。
|
||||
|
||||
让我们一起了解这 4 款基于 web 的开源发票工具,它们很适用于预算紧张的自由职业者和小型企业。2014 年,我在本文的[早期版本][1]中提到了其中两个工具。这 4 个工具用起来都很简单,并且你可以在任何设备上使用它们。
|
||||
|
||||
### Invoice Ninja
|
||||
|
||||
我不是很喜欢 ninja 这个词。尽管如此,我喜欢 [Invoice Ninja][2]。非常喜欢。它将功能融合在一个简单的界面,其中包含一组功能,可让创建,管理和向客户、消费者发送发票。
|
||||
|
||||
您可以轻松配置多个客户端,跟进付款和未结清的发票,生成报价并用电子邮件发送发票。Invoice Ninja 与其竞争对手不同,它[集成][3]了超过 40 个流行支付方式,包括 PayPal,Stripe,WePay 以及 Apple Pay。
|
||||
|
||||
[下载][4]一个可以安装到自己服务器上的版本,或者获取一个[托管版][5]的账户,都可以使用 Invoice Ninja。它有免费版,也有每月 8 美元的收费版。
|
||||
|
||||
### InvoicePlane
|
||||
|
||||
以前,有一个叫做 FusionInvoice 的漂亮的开源发票工具。有一天,FusionInvoice 的开发者将最新版本的代码设为了专有。这件事结局并不完美,因为 FusionInvoice 从 2018 年起再也不开源了。但这不代表这个工具完蛋了。它旧版本的代码依然是开源的,并且再次开发为包括 FusionInvoice 所有优点的新工具 [InvoicePlane][6]。
|
||||
|
||||
只需点几下鼠标即可制作发票。你可以根据需要将它们设为最简或者最详细。一切准备就绪时,你可以用电子邮件发送发票或者输出为 PDF 文件。你还可以为经常开发票的客户或消费者制作定期发票。
|
||||
|
||||
InvoicePlane 不仅可以生成或跟进发票。你还可以为任务或商品创制报价,跟进你销售的产品,查看确认付款,并在发票上生成报告。
|
||||
|
||||
[获取代码][7]并将其安装在你的 Web 服务器上。或者,如果你还没准备好安装它,可以[拿小样][8]试用以下。
|
||||
|
||||
### OpenSourceBilling
|
||||
|
||||
[OpenSourceBilling][9] 被它的开发者称赞为“非常简单的计费软件”,当之无愧。它拥有最简洁的交互界面,配置使用起来轻而易举。
|
||||
|
||||
OpenSourceBilling 因它的商业智能仪表盘脱颖而出,它可以跟进跟进你当前和以前的发票,以及任何没有支付的款项。它以图表的形式整理信息,使之很容易阅读。
|
||||
|
||||
你可以在发票上配置很多信息。只需点几下鼠标按几下键盘,即可添加项目、税率、客户名称以及付款条件。OpenSourceBilling 将这些信息保存在你所有的发票当中,不管新发票还是旧发票。
|
||||
|
||||
与我们之前讨论过的工具一样,OpenSourceBilling 也有可以试用的[程序小样][10]。
|
||||
|
||||
### BambooInvoice
|
||||
|
||||
当我是一个全职自由作家和顾问时,我通过 [BambooInvoice][11] 向客户收费。当它最初的开发者停止维护此软件时,我有点失望。但是 BambooInvoice 又回来了,并一如既往的好。
|
||||
|
||||
BambooInvoice 的简洁很吸引我。它只做一件事并做的很好。你可以创建并修改发票,BambooInvoice 会根据客户和分配的发票编号负责跟进。它会告诉你哪些发票是开放的或过期的。你可以在程序中通过电子邮件发送发票或者导出为 PDF 文件。你还可以生成报告密切关注收入。
|
||||
|
||||
要[安装][12]并使用 BambooInvoice,你需要一个运行 PHP 5 或更高版本的 web 服务器,并运行 MySQL 数据库。机会就在你面前,所以你很乐意去用它。
|
||||
|
||||
你又最喜欢的开源发票工具吗?请自由分享评论。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/18/10/open-source-invoicing-tools
|
||||
|
||||
作者:[Scott Nesbitt][a]
|
||||
选题:[lujun9972](https://github.com/lujun9972)
|
||||
译者:[fuowang](https://github.com/fuowang)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/scottnesbitt
|
||||
[1]: https://opensource.com/business/14/9/4-open-source-invoice-tools
|
||||
[2]: https://www.invoiceninja.org/
|
||||
[3]: https://www.invoiceninja.com/integrations/
|
||||
[4]: https://github.com/invoiceninja/invoiceninja
|
||||
[5]: https://www.invoiceninja.com/invoicing-pricing-plans/
|
||||
[6]: https://invoiceplane.com/
|
||||
[7]: https://wiki.invoiceplane.com/en/1.5/getting-started/installation
|
||||
[8]: https://demo.invoiceplane.com/
|
||||
[9]: http://www.opensourcebilling.org/
|
||||
[10]: http://demo.opensourcebilling.org/
|
||||
[11]: https://www.bambooinvoice.net/
|
||||
[12]: https://sourceforge.net/projects/bambooinvoice/
|
Loading…
Reference in New Issue
Block a user