/* * The Alluxio Open Foundation licenses this work under the Apache License, version 2.0 * (the "License"). You may not use this work except in compliance with the License, which is * available at www.apache.org/licenses/LICENSE-2.0 * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied, as more fully set forth in the License. * * See the NOTICE file distributed with this work for information regarding copyright ownership. */ package alluxio.shell.command; import alluxio.AlluxioURI; import alluxio.Constants; import alluxio.client.file.FileSystem; import alluxio.client.file.URIStatus; import alluxio.client.file.options.ListStatusOptions; import alluxio.exception.AlluxioException; import alluxio.util.FormatUtils; import alluxio.util.SecurityUtils; import alluxio.wire.LoadMetadataType; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Options; import java.io.IOException; import java.util.Collections; import java.util.Comparator; import java.util.List; import javax.annotation.concurrent.ThreadSafe; /** * Displays information for the path specified in args. Depends on different options, this command * can also display the information for all directly children under the path, or recursively. */ @ThreadSafe public final class LsCommand extends WithWildCardPathCommand { public static final String STATE_FOLDER = "Directory"; public static final String STATE_FILE_IN_MEMORY = "In Memory"; public static final String STATE_FILE_NOT_IN_MEMORY = "Not In Memory"; /** * Formats the ls result string. * * @param hSize print human-readable format sizes * @param acl whether security is enabled * @param isFolder whether this path is a file or a folder * @param permission permission string * @param userName user name * @param groupName group name * @param size size of the file in bytes * @param createTimeMs the epoch time in ms when the path is created * @param inMemory whether the file is in memory * @param path path of the file or folder * @return the formatted string according to acl and isFolder */ public static String formatLsString(boolean hSize, boolean acl, boolean isFolder, String permission, String userName, String groupName, long size, long createTimeMs, boolean inMemory, String path) { String memoryState; if (isFolder) { memoryState = STATE_FOLDER; } else { memoryState = inMemory ? STATE_FILE_IN_MEMORY : STATE_FILE_NOT_IN_MEMORY; } String sizeStr = hSize ? FormatUtils.getSizeFromBytes(size) : String.valueOf(size); if (acl) { return String.format(Constants.LS_FORMAT, permission, userName, groupName, sizeStr, CommandUtils.convertMsToDate(createTimeMs), memoryState, path); } else { return String.format(Constants.LS_FORMAT_NO_ACL, sizeStr, CommandUtils.convertMsToDate(createTimeMs), memoryState, path); } } private void printLsString(URIStatus status, boolean hSize) { System.out.print(formatLsString(hSize, SecurityUtils.isSecurityEnabled(), status.isFolder(), FormatUtils.formatMode((short) status.getMode(), status.isFolder()), status.getOwner(), status.getGroup(), status.getLength(), status.getCreationTimeMs(), 100 == status.getInMemoryPercentage(), status.getPath())); } /** * Constructs a new instance to display information for all directories and files directly under * the path specified in args. * * @param fs the filesystem of Alluxio */ public LsCommand(FileSystem fs) { super(fs); } @Override public String getCommandName() { return "ls"; } @Override protected int getNumOfArgs() { return 1; } @Override public Options getOptions() { return new Options() .addOption(RECURSIVE_OPTION) .addOption(FORCE_OPTION) .addOption(LIST_DIR_AS_FILE_OPTION) .addOption(LIST_PINNED_FILES_OPTION) .addOption(LIST_HUMAN_READABLE_OPTION); } /** * Displays information for all directories and files directly under the path specified in args. * * @param path The {@link AlluxioURI} path as the input of the command * @param recursive Whether list the path recursively * @param dirAsFile list the directory status as a plain file * @param hSize print human-readable format sizes */ private void ls(AlluxioURI path, boolean recursive, boolean forceLoadMetadata, boolean dirAsFile, boolean hSize, boolean pinnedOnly) throws AlluxioException, IOException { if (dirAsFile) { URIStatus status = mFileSystem.getStatus(path); if (pinnedOnly && !status.isPinned()) { return; } printLsString(status, hSize); return; } ListStatusOptions options = ListStatusOptions.defaults(); if (forceLoadMetadata) { options.setLoadMetadataType(LoadMetadataType.Always); } List<URIStatus> statuses = listStatusSortedByIncreasingCreationTime(path, options); for (URIStatus status : statuses) { if (!pinnedOnly || status.isPinned()) { printLsString(status, hSize); } if (recursive && status.isFolder()) { ls(new AlluxioURI(path.getScheme(), path.getAuthority(), status.getPath()), true, forceLoadMetadata, false, hSize, pinnedOnly); } } } private List<URIStatus> listStatusSortedByIncreasingCreationTime(AlluxioURI path, ListStatusOptions options) throws AlluxioException, IOException { List<URIStatus> statuses = mFileSystem.listStatus(path, options); Collections.sort(statuses, new Comparator<URIStatus>() { @Override public int compare(URIStatus status1, URIStatus status2) { long t1 = status1.getCreationTimeMs(); long t2 = status2.getCreationTimeMs(); if (t1 < t2) { return -1; } if (t1 == t2) { return 0; } return 1; } }); return statuses; } @Override public void runCommand(AlluxioURI path, CommandLine cl) throws AlluxioException, IOException { ls(path, cl.hasOption("R"), cl.hasOption("f"), cl.hasOption("d"), cl.hasOption("h"), cl.hasOption("p")); } @Override public String getUsage() { return "ls [-d|-f|-p|-R|-h] <path>"; } @Override public String getDescription() { return "Displays information for all files and directories directly under the specified path." + " Specify -d to list directories as plain files." + " Specify -f to force loading files in the directory." + " Specify -p to list all the pinned files." + " Specify -R to display files and directories recursively." + " Specify -h to print human-readable format sizes."; } }